Return a dictionary mapping terms to their Rational coefficient.
Since the dictionary is a defaultdict, inquiries about terms which
were not present will return a coefficient of 0. If an expression is
not an Add it is considered to have a single term.
Return the tuple (R, self/R) where R is the positive Rational
extracted from self. If radical is True (default is False) then
common radicals will be removed and included as a factor of the
primitive expression.
This is the most efficient way to get the head and tail of an
expression.
if you want only the head, use self.args[0];
if you want to process the arguments of the tail then use
self.as_coef_add() which gives the head and a tuple containing
the arguments of the tail when treated as an Add.
if you want the coefficient when self is treated as a Mul
then use self.as_coeff_mul()[0]
This module contains the machinery handling assumptions.
All symbolic objects have assumption attributes that can be accessed via
.is_<assumption name> attribute.
Assumptions determine certain properties of symbolic objects and can
have 3 possible values: True, False, None. True is returned if the
object has the property and False is returned if it doesn’t or can’t
(i.e. doesn’t make sense):
When the property cannot be determined (or when a method is not
implemented) None will be returned, e.g. a generic symbol, x, may or
may not be positive so a value of None is returned for x.is_positive.
By default, all symbolic values are in the largest set in the given context
without specifying the property. For example, a symbol that has a property
being integer, is also real, complex, etc.
object value is a number that can be written as a real
number multiplied by the imaginary unit I. See
[3]_. Please note, that 0 is not considered to be an
imaginary number, see
issue #7649.
Assumption values are stored in obj._assumptions dictionary or
are returned by getter methods (with property decorators) or are
attributes of objects/classes.
Evaluate objects that are not evaluated by default like limits,
integrals, sums and products. All objects of this kind will be
evaluated recursively, unless some species were excluded via ‘hints’
or unless the ‘deep’ hint was set to ‘False’.
xreplace doesn’t differentiate between free and bound symbols. In the
following, subs(x, y) would not change x since it is a bound symbol,
but xreplace does:
Never use self._args, always use self.args.
Only use _args in __new__ when creating a new function.
Don’t override .args() from Basic (so that it’s easy to
change the interface in the future if needed).
By default, only objects that are truly atomic and can’t
be divided into smaller pieces are returned: symbols, numbers,
and number symbols like I and pi. It is possible to request
atoms of any type, however, as demonstrated below.
Examples
>>> from..importI,pi,sin>>> from..abcimportx,y>>> (1+x+2*sin(y+I*pi)).atoms(){1, 2, I, pi, x, y}
If one or more types are given, the results will contain only
those types of atoms.
>>> (1+x+2*sin(y+I*pi)).atoms(Number,NumberSymbol,I){1, 2, I, pi}
Note that I (imaginary unit) and zoo (complex infinity) are special
types of number symbols and are not part of the NumberSymbol class.
The type can be given implicitly, too:
>>> (1+x+2*sin(y+I*pi)).atoms(x)# x is a Symbol{x, y}
Be careful to check your assumptions when using the implicit option
since S(1).is_Integer=True but type(S(1)) is One, a special type
of sympy atom, while type(S(2)) is type Integer and will find all
integers in an expression:
Finally, arguments to atoms() can select more than atomic atoms: any
sympy type (loaded in core/__init__.py) can be listed as an argument
and those types of “atoms” as found in scanning the arguments of the
expression recursively:
Return a dictionary mapping any variable defined in
self.variables as underscore-suffixed numbers
corresponding to their position in self.variables. Enough
underscores are added to ensure that there will be no clash with
existing free symbols.
Return -1, 0, 1 if the object is smaller, equal, or greater than other.
Not in the mathematical sense. If the object is of a different type
from the “other” then their classes are ordered according to
the sorted_classes list.
Evaluate objects that are not evaluated by default like limits,
integrals, sums and products. All objects of this kind will be
evaluated recursively, unless some species were excluded via ‘hints’
or unless the ‘deep’ hint was set to ‘False’.
Return from the atoms of self those which are free symbols.
For most expressions, all symbols are free symbols. For some classes
this is not true. e.g. Integrals use Symbols for the dummy variables
which are bound variables, so Integral has a method to return all
symbols except those. Derivative keeps track of symbols with respect
to which it will perform a derivative; those are
bound variables, too, so it has its own free_symbols method.
Any other method that uses bound variables should implement a
free_symbols method.
Note has is a structural algorithm with no knowledge of
mathematics. Consider the following half-open interval:
>>> from..setsimportInterval>>> i=Interval.Lopen(0,5);iInterval.Lopen(0, 5)>>> i.args(0, 5, True, False)>>> i.has(4)# there is no "4" in the argumentsFalse>>> i.has(0)# there *is* a "0" in the argumentsTrue
Instead, use contains to determine whether a number is in the
interval or not:
>>> i.contains(4)True>>> i.contains(0)False
Note that expr.has(*patterns) is exactly equivalent to
any(expr.has(p)forpinpatterns). In particular, False is
returned when the list of patterns is empty.
A False result does not mean that self cannot be rewritten
into a form that would be comparable. For example, the
difference computed below is zero but without simplification
it does not evaluate to a zero with precision:
Return None when expression (self) does not match
with pattern. Otherwise return a dictionary such that:
pattern.xreplace(self.match(pattern))==self
Examples
>>> from..importWild>>> from..abcimportx,y>>> p=Wild("p")>>> q=Wild("q")>>> r=Wild("r")>>> e=(x+y)**(x+y)>>> e.match(p**p){p_: x + y}>>> e.match(p**q){p_: x + y, q_: x + y}>>> e=(2*x)**2>>> e.match(p*q**r){p_: 4, q_: x, r_: 2}>>> (p*q**r).xreplace(e.match(p*q**r))4*x**2
The old flag will give the old-style pattern matching where
expressions and patterns are essentially solved to give the
match. Both of the following give None unless old=True:
Replace matching subexpressions of self with value.
If map=True then also return the mapping {old: new} where old
was a sub-expression found with query and new is the replacement
value for it. If the expression itself doesn’t match the query, then
the returned value will be self.xreplace(map) otherwise it should
be self.subs(ordered(map.items())).
Traverses an expression tree and performs replacement of matching
subexpressions from the bottom to the top of the tree. The default
approach is to do the replacement in a simultaneous fashion so
changes made are targeted only once. If this is not desired or causes
problems, simultaneous can be set to False. In addition, if an
expression containing more than one Wild symbol is being used to match
subexpressions and the exact flag is True, then the match will only
succeed if non-zero values are received for each Wild that appears in
the match pattern.
The list of possible combinations of queries and replacement values
is listed below:
Rewrites expression containing applications of functions
of one kind in terms of functions of different kind. For
example you can rewrite trigonometric functions as complex
exponentials or combinatorial functions as gamma function.
As a pattern this function accepts a list of functions to
to rewrite (instances of DefinedFunction class). As rule
you can use string or a destination function instance (in
this case rewrite() will use the str() function).
There is also the possibility to pass hints on how to rewrite
the given expressions. For now there is only one such hint
defined called ‘deep’. When ‘deep’ is set to False it will
forbid functions to rewrite their contents.
Substitutes old for new in an expression after sympifying args.
args is either:
two arguments, e.g. foo.subs(old, new)
one iterable argument, e.g. foo.subs(iterable). The iterable may be
o an iterable container with (old, new) pairs. In this case the
replacements are processed in the order given with successive
patterns possibly affecting replacements already made.
o a dict or set whose key/value items correspond to old/new pairs.
In this case the old/new pairs will be sorted by op count and in
case of a tie, by number of args and the default_sort_key. The
resulting sorted list is then processed as an iterable container
(see previous).
If the keyword simultaneous is True, the subexpressions will not be
evaluated until all the substitutions have been made.
In order to obtain a canonical result, unordered iterables are
sorted by count_op length, number of arguments and by the
default_sort_key to break any ties. All other iterables are left
unsorted.
The resulting expression represents a literal replacement of the
old arguments with the new arguments. This may not reflect the
limiting behavior of the expression:
>>> (x**3-3*x).subs({x:oo})nan
>>> limit(x**3-3*x,x,oo)oo
If the substitution will be followed by numerical
evaluation, it is better to pass the substitution to
evalf as
xreplace doesn’t differentiate between free and bound symbols. In the
following, subs(x, y) would not change x since it is a bound symbol,
but xreplace does:
This iterator recursively yields nodes that it has visited in a pre-order
fashion. That is, it yields the current node then descends through the
tree breadth-first to yield all of a node’s children’s pre-order
traversal.
For an expression, the order of the traversal depends on the order of
.args, which in many cases can be arbitrary.
Parameters:
node (sympy expression) – The expression to traverse.
keys ((default None) sort key(s)) – The key(s) used to sort args of Basic objects. When None, args of Basic
objects are processed in arbitrary order. If key is defined, it will
be passed along to ordered() as the only key(s) to use to sort the
arguments; if key is simply True then the default keys of ordered
will be used.
Yields:
subtree (sympy expression) – All of the subtrees in the tree.
Examples
>>> from..importsymbols>>> from.basicimportpreorder_traversal>>> x,y,z=symbols('x y z')
The nodes are returned in the order that they are encountered unless key
is given; simply passing key=True will guarantee that the traversal is
unique.
>>> list(preorder_traversal((x+y)*z,keys=None))[z*(x + y), z, x + y, y, x]>>> list(preorder_traversal((x+y)*z,keys=True))[z*(x + y), z, x + y, x, y]
Reimplementations of constructs introduced in later versions of Python than
we support. Also some functions that are needed SymPy-wide and are located
here for easy import.
Use this as mixin when creating a class which is not supposed to return
true when iterable() is called on its instances. I.e. avoid infinite loop
when calling e.g. list() on the instance
The return value is guaranteed to be equal to the input. ValueError is
raised if the input has a non-integral value.
Examples
>>> from.compatibilityimportas_int>>> from..importsqrt>>> 3.03.0>>> as_int(3.0)# convert to int and test for equality3>>> int(sqrt(10))3>>> as_int(sqrt(10))Traceback (most recent call last):...ValueError: ... is not an integer
This key is supplied by the sort_key routine of Basic objects when
item is a Basic object or an object (other than a string) that
sympifies to a Basic object. Otherwise, this function produces the
key.
The order argument is passed along to the sort_key routine and is
used to determine how the terms within an expression are ordered.
(See examples below) order options are: ‘lex’, ‘grlex’, ‘grevlex’,
and reversed values of the same (e.g. ‘rev-lex’). The default order
value is None (which translates to ‘lex’).
While sort_key is a method only defined for SymPy objects,
default_sort_key will accept anything as an argument so it is
more robust as a sorting key. For the following, using key=
lambda i: i.sort_key() would fail because 2 doesn’t have a sort_key
method; that’s why default_sort_key is used. Note, that it also
handles sympification of non-string items likes ints:
The key returned is useful for getting items into a canonical order
that will be the same across platforms. It is not directly useful for
sorting lists of expressions:
>>> a,b=x,1/x
Since a has only 1 term, its value of sort_key is unaffected by
order:
>>> a.sort_key()==a.sort_key('rev-lex')True
If a and b are combined then the key will differ because there
are terms that can be ordered:
The order of terms obtained when using these keys is the order that would
be obtained if those terms were factors in a product.
Although it is useful for quickly putting expressions in canonical order,
it does not sort expressions based on their complexity defined by the
number of operations, power of variables and others:
Return a boolean indicating whether i is a sequence in the SymPy
sense. If anything that fails the test below should be included as
being a sequence for your application, set ‘include’ to that object’s
type; multiple types should be passed as a tuple of types.
Note: although generators can generate a sequence, they often need special
handling to make sure their elements are captured before the generator is
exhausted, so these are not included by default in the definition of a
sequence.
Return a boolean indicating whether i is SymPy iterable.
True also indicates that the iterator is finite, i.e. you e.g.
call list(…) on the instance.
When SymPy is working with iterables, it is almost always assuming
that the iterable is not a string or a mapping, so those are excluded
by default. If you want a pure Python definition, make exclude=None. To
exclude multiple items, pass them as a tuple.
You can also set the _iterable attribute to True or False on your class,
which will override the checks here, including the exclude test.
As a rule of thumb, some SymPy functions use this to check if they should
recursively map over an object. If an object is technically iterable in
the Python sense but does not desire this behavior (e.g., because its
iteration is not finite, or because iteration might induce an unwanted
computation), it should disable it by setting the _iterable attribute to False.
Return a translation table usable for str.translate().
If there is only one argument, it must be a dictionary mapping Unicode
ordinals (integers) or characters to Unicode ordinals, strings or None.
Character keys will be then converted to ordinals.
If there are two arguments, they must be strings of equal length, and
in the resulting dictionary, each character in x will be mapped to the
character at the same position in y. If there is a third argument, it
must be a string, whose characters will be mapped to None in the result.
Return an iterator of the seq where keys are used to break ties in
a conservative fashion: if, after applying a key, there are no ties
then no other keys will be computed.
Two default keys will be applied if 1) keys are not provided or 2) the
given keys don’t resolve all ties (but only if default is True). The
two keys are _nodes (which places smaller expressions before large) and
default_sort_key which (if the sort_key for an object is defined
properly) should resolve any ties.
If warn is True then an error will be raised if there were no
keys remaining to break ties. This can be used if it was expected that
there should be no ties between items that are not identical.
If warn is True, an error will be raised if there were not
enough keys to break ties:
>>> list(ordered(seq,keys,default=False,warn=True))Traceback (most recent call last):...ValueError: not enough keys to break ties
Notes
The decorated sort is one of the fastest ways to sort a sequence for
which special item comparison is desired: the sequence is decorated,
sorted on the basis of the decoration (e.g. making all letters lower
case) and then undecorated. If one wants to break ties for items that
have the same decorated value, a second key can be used. But if the
second key is expensive to compute then it is inefficient to decorate
all items with both keys: only those items having identical first key
values need to be decorated. This function applies keys successively
only when needed to break ties. By yielding an iterator, use of the
tie-breaker is delayed as long as possible.
This function is best used in cases when use of the first key is
expected to be a good hashing function; if there are no unique hashes
from application of a key then that key should not have been used. The
exception, however, is that even if there are many collisions, if the
first group is small and one does not need to process all items in the
list then time will not be wasted sorting what one was not interested
in. For example, if one were looking for the minimum in a list and
there were several criteria used to define the sort order, then this
function would be good at returning that quickly if the first group
of candidates is small relative to the number of items being processed.
That is, the first argument is the metaclass, and the remaining arguments
are the base classes. Note that if the base class is just object, you
may omit it.
The Dict is a subclass of Basic, so that it works well in the
SymPy framework. Because it is immutable, it may be included
in sets, but its values must all be given at instantiation and
cannot be changed afterwards. Otherwise it behaves identically
to the Python dict.
>>> from.containersimportDict
>>> D=Dict({1:'one',2:'two'})>>> forkeyinD:... ifkey==1:... print('%s%s'%(key,D[key]))1 one
The args are sympified so the 1 and 2 are Integers and the values
are Symbols. Queries automatically sympify args so the following work:
>>> 1inDTrue>>> D.has('one')# searches keys and valuesTrue>>> 'one'inD# not in the keysFalse>>> D[1]one
Never use self._args, always use self.args.
Only use _args in __new__ when creating a new function.
Don’t override .args() from Basic (so that it’s easy to
change the interface in the future if needed).
The Tuple is a subclass of Basic, so that it works well in the
SymPy framework. The wrapped tuple is available as self.args, but
you can also access elements or slices with [:] syntax.
Parameters:
sympify (bool) – If False, sympify is not called on args. This
can be used for speedups for very large tuples where the
elements are known to already be sympy objects.
Example
>>> from..importsymbols>>> from.containersimportTuple>>> a,b,c,d=symbols('a b c d')>>> Tuple(a,b,c)[1:](b, c)>>> Tuple(a,b,c).subs(a,d)(d, b, c)
Decorator that converts any tuple in the function arguments into a Tuple.
The motivation for this is to provide simple user interfaces. The user can
call a function with regular tuples in the argument, and the wrapper will
convert them to Tuples before handing them to the function.
Registries map a name to an object using attribute notation. Registry
classes behave singletonically: all their instances share the same state,
which is stored in the class object.
A decorator for binary special methods to handle _op_priority.
Binary special methods in Expr and its subclasses use a special attribute
‘_op_priority’ to determine whose special method will be called to
handle the operation. In general, the object having the highest value of
‘_op_priority’ will handle the operation. Expr and subclasses that define
custom binary special methods (__mul__, etc.) should decorate those
methods with this decorator to add the priority logic.
The method_name argument is the name of the method of the other class
that will be called. Use this decorator in the following manner:
# Call other.__rmul__ if other._op_priority > self._op_priority@call_highest_priority('__rmul__')def__mul__(self,other):...# Call other.__mul__ if other._op_priority > self._op_priority@call_highest_priority('__mul__')def__rmul__(self,other):...
Evaluate the given formula to an accuracy of n digits.
Optional keyword arguments:
subs=<dict>
Substitute numerical values for symbols, e.g.
subs={x:3, y:1+pi}. The substitutions must be given as a
dictionary.
maxn=<integer>
Allow a maximum temporary working precision of maxn digits
(default=100)
chop=<bool>
Replace tiny real or imaginary parts in subresults
by exact zeros (default=False)
strict=<bool>
Raise PrecisionExhausted if any subresult fails to evaluate
to full accuracy, given the available maxprec
(default=False)
quad=<str>
Choose algorithm for numerical quadrature. By default,
tanh-sinh quadrature is used. For oscillatory
integrals on an infinite interval, try quad=’osc’.
Evaluate the given formula to an accuracy of n digits.
Optional keyword arguments:
subs=<dict>
Substitute numerical values for symbols, e.g.
subs={x:3, y:1+pi}. The substitutions must be given as a
dictionary.
maxn=<integer>
Allow a maximum temporary working precision of maxn digits
(default=100)
chop=<bool>
Replace tiny real or imaginary parts in subresults
by exact zeros (default=False)
strict=<bool>
Raise PrecisionExhausted if any subresult fails to evaluate
to full accuracy, given the available maxprec
(default=False)
quad=<str>
Choose algorithm for numerical quadrature. By default,
tanh-sinh quadrature is used. For oscillatory
integrals on an infinite interval, try quad=’osc’.
Helper for evalf_add. Adds a list of (mpfval, accuracy) terms.
Returns:
- None, None if there are no non-zero terms;
- terms[0] if there is only 1 term;
- scaled_zero if the sum of the terms produces a zero by cancellation – e.g. mpfs representing 1 and -1 would produce a scaled zero which need
special handling since they are not actually zero and they are purposely
malformed to ensure that they can’t be used in anything but accuracy
calculations;
- a tuple that is scaled to target_prec that corresponds to the – sum of the terms.
The returned mpf tuple will be normalized to target_prec; the input
prec is used to define the working precision.
XXX explain why this is needed and why one can’t just loop using mpf_add
Returns relative accuracy of a complex number with given accuracies
for the real and imaginary parts. The relative accuracy is defined
in the complex norm sense as ||z|+|error|| / |z| where error
is equal to (real absolute error) + (imag absolute error)*i.
The full expression for the (logarithmic) error can be approximated
easily by using the max norm to approximate the complex norm.
In the worst case (re and im equal), this is wrong by a factor
sqrt(2), or by log2(sqrt(2)) = 0.5 bit.
Fast approximation of log2(x) for an mpf value tuple x.
Notes: Calculated as exponent + width of mantissa. This is an
approximation for two reasons: 1) it gives the ceil(log2(abs(x)))
value and 2) it is too high by 1 in the case that x is an exact
power of 2. Although this is easy to remedy by testing to see if
the odd mpf mantissa is 1 (indicating that one was dealing with
an exact power of 2) that would decrease the speed and is not
necessary as this is only being used as an approximation for the
number of bits in x. The correct return value could be written as
“x[2] + (x[3] if x[1] != 1 else 0)”.
Since mpf tuples always have an odd mantissa, no check is done
to see if the mantissa is a multiple of 2 (in which case the
result would be too large by 1).
modelparameters.sympy.core.evalf.get_complex_part(expr, no, prec, options)[source]¶
no = 0 for real part, no = 1 for imaginary part
modelparameters.sympy.core.evalf.get_integer_part(expr, no, options, return_ints=False)[source]¶
With no = 1, computes ceiling(expr)
With no = -1, computes floor(expr)
Note: this function either gives the exact result or signals failure.
modelparameters.sympy.core.evalf.hypsum(expr, n, start, prec)[source]¶
Sum a rapidly convergent infinite hypergeometric series with
given general term, e.g. e = hypsum(1/factorial(n), n). The
quotient between successive terms must be a quotient of integer
polynomials.
Return a and b if v matches a + I*b where b is not zero and
a and b are Numbers, else None. If or_real is True then 0 will
be returned for b if v is a real number.
Return an mpf representing a power of two with magnitude mag
and -1 for precision. Or, if mag is a scaled_zero tuple, then just
remove the sign from within the list that it was initially wrapped
in.
This context managers controls whether or not all SymPy functions evaluate
by default.
Note that much of SymPy expects evaluated expressions. This functionality
is experimental and is unlikely to function as intended on large
expressions.
Examples
>>> from..abcimportx>>> from.evaluateimportevaluate>>> print(x+x)2*x>>> withevaluate(False):... print(x+x)x + x
Everything that requires arithmetic operations to be defined
should subclass this class, instead of Basic (which should be
used only for argument storage and expression manipulation, i.e.
pattern matching, substitutions, etc).
Return [commutative factors, non-commutative factors] of self.
self is treated as a Mul and the ordering of the factors is maintained.
If cset is True the commutative factors will be returned in a set.
If there were repeated factors (as may happen with an unevaluated Mul)
then an error will be raised unless it is explicitly supressed by
setting warn to False.
Note: -1 is always separated from a Number unless split_1 is False.
Return the tuple (c, args) where self is written as an Add, a.
c should be a Rational added to any terms of the Add that are
independent of deps.
args should be a tuple of all other terms of a; args is empty
if self is a Number or if self is independent of deps (when given).
This should be used when you don’t know if self is an Add or not but
you want to treat self as an Add or if you want to process the
individual arguments of the tail of self as an Add.
if you know self is an Add and want only the head, use self.args[0];
if you don’t want to process the arguments of the tail but need the
tail then use self.as_two_terms() which gives the head and tail.
if you want to split self into an independent and dependent parts
use self.as_independent(*deps)
Return the tuple (c, args) where self is written as a Mul, m.
c should be a Rational multiplied by any factors of the Mul that are
independent of deps.
args should be a tuple of all other factors of m; args is empty
if self is a Number or if self is independent of deps (when given).
This should be used when you don’t know if self is a Mul or not but
you want to treat self as a Mul or if you want to process the
individual arguments of the tail of self as a Mul.
if you know self is a Mul and want only the head, use self.args[0];
if you don’t want to process the arguments of the tail but need the
tail then use self.as_two_terms() which gives the head and tail;
if you want to split self into an independent and dependent parts
use self.as_independent(*deps)
Extracts symbolic coefficient at the given expression. In
other words, this functions separates ‘self’ into the product
of ‘expr’ and ‘expr’-free coefficient. If such separation
is not possible it will return None.
Two terms have E in them so a sum is returned. (If one were
desiring the coefficient of the term exactly matching E then
the constant from the returned expression could be selected.
Or, for greater precision, a method of Poly can be used to
indicate the desired term from which the coefficient is
desired.)
>>> (2*E+x*E).as_coefficient(E)x + 2>>> _.args[0]# just want the exact match2>>> p=Poly(2*E+x*E);pPoly(x*E + 2*E, x, E, domain='ZZ')>>> p.coeff_monomial(E)2>>> p.nth(0,1)2
Since the following cannot be written as a product containing
E as a factor, None is returned. (If the coefficient 2*x is
desired then the coeff method should be used.)
Return a dictionary mapping terms to their Rational coefficient.
Since the dictionary is a defaultdict, inquiries about terms which
were not present will return a coefficient of 0. If an expression is
not an Add it is considered to have a single term.
This method should recursively remove a Rational from all arguments
and return that (content) and the new self (primitive). The content
should always be positive and Mul(*foo.as_content_primitive())==foo.
The primitive need no be in canonical form and should try to preserve
the underlying structure if possible (i.e. expand_mul should not be
applied to self).
Examples
>>> from..importsqrt>>> from..abcimportx,y,z
>>> eq=2+2*x+2*y*(3+3*y)
The as_content_primitive function is recursive and retains structure:
>>> eq.as_content_primitive()(2, x + 3*y*(y + 1) + 1)
Integer powers will have Rationals extracted from the base:
If clear=False (default is True) then content will not be removed
from an Add if it can be distributed to leave one or more
terms with integer coefficients.
>>> (x/2+y).as_content_primitive()(1/2, x + 2*y)>>> (x/2+y).as_content_primitive(clear=False)(1, x/2 + y)
A mostly naive separation of a Mul or Add into arguments that are not
are dependent on deps. To obtain as complete a separation of variables
as possible, use a separation method first, e.g.:
separatevars() to change Mul, Add and Pow (including exp) into Mul
.expand(mul=True) to change Add or Mul into Add
.expand(log=True) to change log expr into an Add
The only non-naive thing that is done here is to respect noncommutative
ordering of variables and to always return (0, 0) for self of zero
regardless of hints.
For nonzero self, the returned tuple (i, d) has the
following interpretation:
i will has no variable that appears in deps
d will be 1 or else have terms that contain variables that are in deps
if self is an Add then self = i + d
if self is a Mul then self = i*d
otherwise (self, S.One) or (S.One, self) is returned.
To force the expression to be treated as an Add, use the hint as_Add=True
Note: when trying to get independent terms, a separation method
might need to be used first. In this case, it is important to keep
track of what you send to this routine so you know how to interpret
the returned values
>>> from..importseparatevars,log>>> separatevars(exp(x+y)).as_independent(x)(exp(y), exp(x))>>> (x+x*y).as_independent(y)(x, x*y)>>> separatevars(x+x*y).as_independent(y)(x, y + 1)>>> (x*(1+y)).as_independent(y)(x, y + 1)>>> (x*(1+y)).expand(mul=True).as_independent(y)(x, x*y)>>> a,b=symbols('a b',positive=True)>>> (log(a*b).expand(log=True)).as_independent(b)(log(a), log(b))
Return self as a dictionary of factors with each factor being
treated as a power. The keys are the bases of the factors and the
values, the corresponding exponents. The resulting dictionary should
be used with caution if the expression is a Mul and contains non-
commutative factors since the order that they appeared will be lost in
the dictionary.
Performs complex expansion on ‘self’ and returns a tuple
containing collected both real and imaginary parts. This
method can’t be confused with re() and im() functions,
which does not perform complex expansion at evaluation.
However it is possible to expand both re() and im()
functions and get exactly the same results as with
a single call to this function.
Canonical way to choose an element in the set {e, -e} where
e is any expression. If the canonical element is e, we have
e.could_extract_minus_sign() == True, else
e.could_extract_minus_sign() == False.
For any expression, the set {e.could_extract_minus_sign(),(-e).could_extract_minus_sign()} must be {True,False}.
Return True if self == other, False if it doesn’t, or None. If
failing_expression is True then the expression which did not simplify
to a 0 will be returned instead of None.
If self is a Number (or complex number) that is not zero, then
the result is False.
If self is a number and has not evaluated to zero, evalf will be
used to test whether the expression evaluates to zero. If it does so
and the result has significance (i.e. the precision is either -1, for
a Rational result, or is greater than 1) then the evalf value will be
used to return True or False.
This tests whether a given expression is algebraic or not, in the
given symbols, syms. When syms is not given, all free symbols
will be used. The rational function does not have to be in expanded
or in any kind of canonical form.
This function returns False for expressions that are “algebraic
expressions” with symbolic exponents. This is a simple extension to the
is_rational_function, including rational exponentiation.
This function does not attempt any nontrivial simplifications that may
result in an expression that does not appear to be an algebraic
expression to become one.
Return True if self is constant, False if not, or None if
the constancy could not be determined conclusively.
If an expression has no free symbols then it is a constant. If
there are free symbols it is possible that the expression is a
constant, perhaps (but not necessarily) zero. To test such
expressions, two strategies are tried:
1) numerical evaluation at two random points. If two such evaluations
give two different values and the values have a precision greater than
1 then self is not constant. If the evaluations agree or could not be
obtained with any precision, no decision is made. The numerical testing
is done only if wrt is different than the free symbols.
2) differentiation with respect to variables in ‘wrt’ (or all free
symbols if omitted) to see if the expression is constant or not. This
will not always lead to an expression that is zero even though an
expression is constant (see added test in test_expr.py). If
all derivatives are zero then self is constant with respect to the
given symbols.
If neither evaluation nor differentiation can prove the expression is
constant, None is returned unless two numerical values happened to be
the same and the flag failing_number is True – in that case the
numerical value will be returned.
If flag simplify=False is passed, self will not be simplified;
the default is True since self should be simplified before testing.
>>> (0**x).is_constant()False>>> x.is_constant()False>>> (x**x).is_constant()False>>> one=cos(x)**2+sin(x)**2>>> one.is_constant()True>>> ((one-1)**(x+1)).is_constant()in(True,False)# could be 0 or 1True
Returns True if self has no free symbols.
It will be faster than ifnotself.free_symbols, however, since
is_number will fail as soon as it hits a free symbol.
Return True if self is a polynomial in syms and False otherwise.
This checks if self is an exact polynomial in syms. This function
returns False for expressions that are “polynomials” with symbolic
exponents. Thus, you should be able to apply polynomial algorithms to
expressions for which this returns True, and Poly(expr, *syms) should
work if and only if expr.is_polynomial(*syms) returns True. The
polynomial does not have to be in expanded form. If no symbols are
given, all free symbols in the expression will be used.
This is not part of the assumptions system. You cannot do
Symbol(‘z’, polynomial=True).
Test whether function is a ratio of two polynomials in the given
symbols, syms. When syms is not given, all free symbols will be used.
The rational function does not have to be in expanded or in any kind of
canonical form.
This function returns False for expressions that are “rational
functions” with symbolic exponents. Thus, you should be able to call
.as_numer_denom() and apply polynomial algorithms to the result for
expressions for which this returns True.
This is not part of the assumptions system. You cannot do
Symbol(‘z’, rational_function=True).
This function does not attempt any nontrivial simplifications that may
result in an expression that does not appear to be a rational function
to become one.
Wrapper for series yielding an iterator of the terms of the series.
Note: an infinite series will yield an infinite iterator. The following,
for exaxmple, will never terminate. It will just keep printing terms
of the sin(x) series:
forterminsin(x).lseries(x):printterm
The advantage of lseries() over nseries() is that many times you are
just interested in the next term in the series (i.e. the first term for
example), but you don’t know how many you should ask for in nseries()
using the “n” parameter.
Wrapper to _eval_nseries if assumptions allow, else to series.
If x is given, x0 is 0, dir=’+’, and self has x, then _eval_nseries is
called. This calculates “n” terms in the innermost expressions and
then builds up the final series just by “cross-multiplying” everything
out.
The optional logx parameter can be used to replace any log(x) in the
returned series with a symbolic value to avoid evaluating log(x) at 0. A
symbol to use in place of log(x) should be provided.
Advantage – it’s fast, because we don’t have to determine how many
terms we need to calculate in advance.
Disadvantage – you may end up with less terms than you may have
expected, but the O(x**n) term appended will always be correct and
so the result, though perhaps shorter, will also be correct.
If any of those assumptions is not met, this is treated like a
wrapper to series which will try harder to return the correct
number of terms.
Handling of the logx parameter — in the following example the
expansion fails since sin does not have an asymptotic expansion
at -oo (the limit of log(x) as x approaches 0):
Return the positive Rational that can be extracted non-recursively
from every term of self (i.e., self is treated like an Add). This is
like the as_coeff_Mul() method but primitive always extracts a positive
Rational (never a negative or a Float).
Do not confuse the Python builtin function, round, with the
SymPy method of the same name. The former always returns a float
(or raises an error if applied to a complex value) while the
latter returns either a Number or a complex number:
Series expansion of “self” around x=x0 yielding either terms of
the series one by one (the lazy series given when n=None), else
all the terms at once when n != None.
Returns the series expansion of “self” around the point x=x0
with respect to x up to O((x-x0)**n,x,x0) (default n is 6).
If x=None and self is univariate, the univariate symbol will
be supplied, otherwise an error will be raised.
For dir=+ (default) the series is calculated from the right and
for dir=- the series from the left. For smooth functions this
flag will not alter the results.
Evaluate objects that are not evaluated by default like limits,
integrals, sums and products. All objects of this kind will be
evaluated recursively, unless some species were excluded via ‘hints’
or unless the ‘deep’ hint was set to ‘False’.
Factors treats its factors as though they are all in the numerator, so
if you violate this assumption the results will be correct but will
not strictly correspond to the numerator and denominator of the ratio:
>>> a.div(x/z)(Factors({y: 2}), Factors({z: -1}))
Factors is also naive about bases: it does not attempt any denesting
of Rational-base terms, for example the following does not become
2**(2*x)/2.
Return self and other with gcd removed from each.
The only differences between this and method div is that this
is 1) optimized for the case when there are few factors in common and
2) this does not raise an error if other is zero.
>>> from.exprtoolsimportFactors>>> from..abcimportx,y,z>>> a=Factors((x*y**2).as_powers_dict())>>> b=Factors((x*y/z).as_powers_dict())>>> a.quo(b)# same as a/bFactors({y: 1})
Decompose power into symbolic base and integer exponent.
This is strictly only valid if the exponent from which
the integer is extracted is itself an integer or the
base is positive. These conditions are assumed and not
checked here.
Remove common factors from terms in all arguments without
changing the underlying structure of the expr. No expansion or
simplification (and no processing of non-commutatives) is performed.
If radical=True then a radical common to all terms will be factored
out of any Add sub-expressions of the expr.
If clear=False (default) then coefficients will not be separated
from a single Add if they can be distributed to leave one or more
terms with integer coefficients.
If fraction=True (default is False) then a common denominator will be
constructed for the expression.
If sign=True (default) then even if the only factor in common is a -1,
it will be factored out of the expression.
terms can be an expression or a non-Basic sequence of expressions
which will be handled as though they are terms from a sum.
If isprimitive is True the _gcd_terms will not run the primitive
method on the terms.
clear controls the removal of integers from the denominator of an Add
expression. When True (default), all numerical denominator will be cleared;
when False the denominators will be cleared only if all terms had numerical
denominators other than 1.
fraction, when True (default), will put the expression over a common
denominator.
For rule-based inference engines, the classical work is RETE algorithm [1],
[2] Although we are not implementing it in full (or even significantly)
it’s still still worth a read to understand the underlying ideas.
In short, every rule in a system of rules is one of two forms:
atom -> … (alpha rule)
And(atom1, atom2, …) -> … (beta rule)
The major complexity is in efficient beta-rules processing and usually for an
expert system a lot of effort goes into code that operates on beta-rules.
Here we take minimalistic approach to get something usable first.
(preparation) of alpha- and beta- networks, everything except
(runtime) FactRules.deduce_all_facts
( Kirr: I’ve never thought that doing )
( logic stuff is that difficult… )
Rules that describe how to deduce facts in logic space
When defined, these rules allow implications to quickly be determined
for a set of facts. For this precomputed deduction tables are used.
see deduce_all_facts (forward-chaining)
Also it is possible to gather prerequisites for a fact, which is tried
to be proven. (backward-chaining)
.full_implications[k, v]: all the implications of fact k=v
.beta_triggers[k, v]: beta rules that might be triggered when k=v
.prereq – {} k <- [] of k’s prerequisites
we build prerequisites (from what points something can be deduced):
b <- a
c <- a, b
rules: {} of a -> [b, c, …]
return: {} of c <- [a, b, …]
Note however, that this prerequisites may be not enough to prove a
fact. An example is ‘a -> b’ rule, where prereq(a) is b, and prereq(b)
is a. That’s because a=T -> b=T, and b=F -> a=F, but a=F -> b=?
Returns a canonical form of cls applied to arguments args.
The eval() method is called when the class cls is about to be
instantiated and it should return either some simplified instance
(possible of some other class), or if the class cls should be
unmodified, return None.
Carries out differentiation of the given expression with respect to symbols.
expr must define ._eval_derivative(symbol) method that returns
the differentiation result. This function only needs to consider the
non-trivial case where expr contains symbol and it should call the diff()
method internally (not _eval_derivative); Derivative should be the only
one to call _eval_derivative.
Simplification of high-order derivatives:
Because there can be a significant amount of simplification that can be
done when multiple differentiations are performed, results will be
automatically simplified in a fairly conservative fashion unless the
keyword simplify is set to False.
If evaluate is set to True and the expression can not be evaluated, the
list of differentiation symbols will be sorted, that is, the expression is
assumed to have continuous derivatives up to the order asked. This sorting
assumes that derivatives wrt Symbols commute, derivatives wrt non-Symbols
commute, but Symbol and non-Symbol derivatives don’t commute with each
other.
Derivative wrt non-Symbols:
This class also allows derivatives wrt non-Symbols that have _diff_wrt
set to True, such as Function and Derivative. When a derivative wrt a non-
Symbol is attempted, the non-Symbol is temporarily converted to a Symbol
while the differentiation is performed.
Note that this may seem strange, that Derivative allows things like
f(g(x)).diff(g(x)), or even f(cos(x)).diff(cos(x)). The motivation for
allowing this syntax is to make it easier to work with variational calculus
(i.e., the Euler-Lagrange method). The best way to understand this is that
the action of derivative with respect to a non-Symbol is defined by the
above description: the object is substituted for a Symbol and the
derivative is taken with respect to that. This action is only allowed for
objects for which this can be done unambiguously, for example Function and
Derivative objects. Note that this leads to what may appear to be
mathematically inconsistent results. For example:
This appears wrong because in fact 2*cos(x) and 2*sqrt(1 - sin(x)**2) are
identically equal. However this is the wrong way to think of this. Think
of it instead as if we have something like this:
Here, the Symbols c and s act just like the functions cos(x) and sin(x),
respectively. Think of 2*cos(x) as f(c).subs(c, cos(x)) (or f(c) at
c = cos(x)) and 2*sqrt(1 - sin(x)**2) as g(s).subs(s, sin(x)) (or g(s) at
s = sin(x)), where f(u) == 2*u and g(u) == 2*sqrt(1 - u**2). Here, we
define the function first and evaluate it at the function, but we can
actually unambiguously do this in reverse in SymPy, because
expr.subs(Function, Symbol) is well-defined: just structurally replace the
function everywhere it appears in the expression.
This is the same notational convenience used in the Euler-Lagrange method
when one says F(t, f(t), f’(t)).diff(f(t)). What is actually meant is
that the expression in question is represented by some F(t, u, v) at u =
f(t) and v = f’(t), and F(t, f(t), f’(t)).diff(f(t)) simply means F(t, u,
v).diff(u) at u = f(t).
We do not allow derivatives to be taken with respect to expressions where this
is not so well defined. For example, we do not allow expr.diff(x*y)
because there are multiple ways of structurally defining where x*y appears
in an expression, some of which may surprise the reader (for example, a
very strict definition would have that (x*y*z).diff(x*y) == 0).
Note that this definition also fits in nicely with the definition of the
chain rule. Note how the chain rule in SymPy is defined using unevaluated
Subs objects:
Finally, note that, to be consistent with variational calculus, and to
ensure that the definition of substituting a Function for a Symbol in an
expression is well-defined, derivatives of functions are assumed to not be
related to the function. In other words, we have:
>>> from..importdiff>>> diff(f(x),x).diff(f(x))0
The same is true for derivatives of different orders:
Expresses a Derivative instance as a finite difference.
Parameters:
points (sequence or coefficient, optional) – If sequence: discrete values (length >= order+1) of the
independent variable used for generating the finite
difference weights.
If it is a coefficient, it will be used as the step-size
for generating an equidistant sequence of length order+1
centered around x0. Default: 1 (step-size 1)
x0 (number or Symbol, optional) – the value of the independent variable (wrt) at which the
derivative is to be approximated. Default: same as wrt.
wrt (Symbol, optional) – “with respect to” the variable for which the (partial)
derivative is to be approximated for. If not provided it
is required that the derivative is ordinary. Default: None.
The algorithm is not restricted to use equidistant spacing, nor
do we need to make the approximation around x0, but we can get
an expression estimating the derivative at an offset:
Evaluate objects that are not evaluated by default like limits,
integrals, sums and products. All objects of this kind will be
evaluated recursively, unless some species were excluded via ‘hints’
or unless the ‘deep’ hint was set to ‘False’.
Return from the atoms of self those which are free symbols.
For most expressions, all symbols are free symbols. For some classes
this is not true. e.g. Integrals use Symbols for the dummy variables
which are bound variables, so Integral has a method to return all
symbols except those. Derivative keeps track of symbols with respect
to which it will perform a derivative; those are
bound variables, too, so it has its own free_symbols method.
Any other method that uses bound variables should implement a
free_symbols method.
In the following example Function is used as a base class for
my_func that represents a mathematical function my_func. Suppose
that it is well known, that my_func(0) is 1 and my_func at infinity
goes to 0, so we want those two simplifications to occur automatically.
Suppose also that my_func(x) is real exactly when x is real. Here is
an implementation that honours those requirements:
In order for my_func to become useful, several other methods would
need to be implemented. See source code of some of the already
implemented functions for more complete examples.
Also, if the function can take more than one argument, then nargs
must be defined, e.g. if my_func can take one or two arguments
then,
The undefined function, after application, also has the nargs
attribute; the actual number of arguments is always available by
checking the args attribute:
Lambda(x, expr) represents a lambda function similar to Python’s
‘lambda x: expr’. A function of several variables is written as
Lambda((x, y, …), expr).
Return from the atoms of self those which are free symbols.
For most expressions, all symbols are free symbols. For some classes
this is not true. e.g. Integrals use Symbols for the dummy variables
which are bound variables, so Integral has a method to return all
symbols except those. Derivative keeps track of symbols with respect
to which it will perform a derivative; those are
bound variables, too, so it has its own free_symbols method.
Any other method that uses bound variables should implement a
free_symbols method.
Represents unevaluated substitutions of an expression.
Subs(expr,x,x0) receives 3 arguments: an expression, a variable or
list of distinct variables and a point or list of evaluation points
corresponding to those variables.
Subs objects are generally useful to represent unevaluated derivatives
calculated at a point.
The variables may be expressions, but they are subjected to the limitations
of subs(), so it is usually a good practice to use only symbols for
variables, since in that case there can be no ambiguity.
There’s no automatic expansion - use the method .doit() to effect all
possible substitutions of the object and also of objects inside the
expression.
When evaluating derivatives at a point that is not a symbol, a Subs object
is returned. One is also able to calculate derivatives of Subs objects - in
this case the expression is always expanded (for the unevaluated form, use
Derivative()).
Evaluate objects that are not evaluated by default like limits,
integrals, sums and products. All objects of this kind will be
evaluated recursively, unless some species were excluded via ‘hints’
or unless the ‘deep’ hint was set to ‘False’.
Evaluate the given formula to an accuracy of n digits.
Optional keyword arguments:
subs=<dict>
Substitute numerical values for symbols, e.g.
subs={x:3, y:1+pi}. The substitutions must be given as a
dictionary.
maxn=<integer>
Allow a maximum temporary working precision of maxn digits
(default=100)
chop=<bool>
Replace tiny real or imaginary parts in subresults
by exact zeros (default=False)
strict=<bool>
Raise PrecisionExhausted if any subresult fails to evaluate
to full accuracy, given the available maxprec
(default=False)
quad=<str>
Choose algorithm for numerical quadrature. By default,
tanh-sinh quadrature is used. For oscillatory
integrals on an infinite interval, try quad=’osc’.
Return from the atoms of self those which are free symbols.
For most expressions, all symbols are free symbols. For some classes
this is not true. e.g. Integrals use Symbols for the dummy variables
which are bound variables, so Integral has a method to return all
symbols except those. Derivative keeps track of symbols with respect
to which it will perform a derivative; those are
bound variables, too, so it has its own free_symbols method.
Any other method that uses bound variables should implement a
free_symbols method.
Evaluate the given formula to an accuracy of n digits.
Optional keyword arguments:
subs=<dict>
Substitute numerical values for symbols, e.g.
subs={x:3, y:1+pi}. The substitutions must be given as a
dictionary.
maxn=<integer>
Allow a maximum temporary working precision of maxn digits
(default=100)
chop=<bool>
Replace tiny real or imaginary parts in subresults
by exact zeros (default=False)
strict=<bool>
Raise PrecisionExhausted if any subresult fails to evaluate
to full accuracy, given the available maxprec
(default=False)
quad=<str>
Choose algorithm for numerical quadrature. By default,
tanh-sinh quadrature is used. For oscillatory
integrals on an infinite interval, try quad=’osc’.
To match functions with a range of arguments, set nargs to a tuple
containing the desired number of arguments, e.g. if nargs=(1,2)
then functions with 1 or 2 arguments will be matched.
Return a representation (integer or expression) of the operations in expr.
If visual is False (default) then the sum of the coefficients of the
visual expression will be returned.
If visual is True then the number of each type of operation is shown
with the core class types (or their virtual equivalent) multiplied by the
number of times they occur.
If expr is an iterable, the sum of the op counts of the
items will be returned.
In the following, an Add, Mul, Pow and two functions:
>>> (sin(x)*x+sin(x)**2).count_ops(visual=True)ADD + MUL + POW + 2*SIN
for a total of 5:
>>> (sin(x)*x+sin(x)**2).count_ops(visual=False)5
Note that “what you type” is not always what you get. The expression
1/x/y is translated by sympy into 1/(x*y) so it gives a DIV and MUL rather
than two DIVs:
>>> (1/x/y).count_ops(visual=True)DIV + MUL
The visual option can be used to demonstrate the difference in
operations for expressions in different forms. Here, the Horner
representation is compared with the expanded form of a polynomial:
This is just a wrapper to unify .diff() and the Derivative class; its
interface is similar to that of integrate(). You can use the same
shortcuts for multiple variables as with Derivative. For example,
diff(f(x), x, x, x) and diff(f(x), x, 3) both return the third derivative
of f(x).
You can pass evaluate=False to get an unevaluated Derivative class. Note
that if there are 0 symbols (such as diff(f(x), x, 0), then the result will
be the function (the zeroth derivative), even if evaluate=False.
Expand an expression using methods given as hints.
Hints evaluated unless explicitly set to False are: basic, log,
multinomial, mul, power_base, and power_exp The following
hints are supported but not applied unless set to True: complex,
func, and trig. In addition, the following meta-hints are
supported by some or all of the other hints: frac, numer,
denom, modulus, and force. deep is supported by all
hints. Additionally, subclasses of Expr may define their own hints or
meta-hints.
The basic hint is used for any special rewriting of an object that
should be done automatically (along with the other hints like mul)
when expand is called. This is a catch-all hint to handle any sort of
expansion that may not be described by the existing hint names. To use
this hint an object should override the _eval_expand_basic method.
Objects may also define their own expand methods, which are not run by
default. See the API section below.
If deep is set to True (the default), things like arguments of
functions are recursively expanded. Use deep=False to only expand on
the top level.
If the force hint is used, assumptions about variables will be ignored
in making the expansion.
Pull out power of an argument as a coefficient and split logs products
into sums of logs.
Note that these only work if the arguments of the log function have the
proper assumptions–the arguments must be positive and the exponents must
be real–or else the force hint must be True:
Note that this is just a wrapper around as_real_imag(). Most objects
that wish to redefine _eval_expand_complex() should consider
redefining as_real_imag() instead.
Note that the forms of sin(n*x) and cos(n*x) in terms of sin(x)
and cos(x) are not unique, due to the identity sin^2(x) + cos^2(x)
= 1. The current implementation uses the form obtained from Chebyshev
polynomials, but this may change. See this MathWorld article for more
information.
Hints are applied in an arbitrary, but consistent order (in the current
implementation, they are applied in alphabetical order, except
multinomial comes before mul, but this may change). Because of this,
some hints may prevent expansion by other hints if they are applied
first. For example, mul may distribute multiplications and prevent
log and power_base from expanding them. Also, if mul is
applied before multinomial`,theexpressionmightnotbefullydistributed.Thesolutionistousethevarious``expand_hint helper
functions or to use hint=False to this function to finely control
which hints are applied. Here are some examples:
Objects can define their own expand hints by defining
_eval_expand_hint(). The function should take the form:
def_eval_expand_hint(self,**hints):# Only apply the method to the top-level expression...
See also the example below. Objects should define _eval_expand_hint()
methods only if hint applies to that specific object. The generic
_eval_expand_hint() method defined in Expr will handle the no-op case.
Each hint should be responsible for expanding that hint only.
Furthermore, the expansion should be applied to the top-level expression
only. expand() takes care of the recursion that happens when
deep=True.
You should only call _eval_expand_hint() methods directly if you are
100% sure that the object has the method, as otherwise you are liable to
get unexpected AttributeError``s.Note,again,thatyoudonotneedtorecursivelyapplythehinttoargsofyourobject:thisishandledautomaticallyby``expand(). _eval_expand_hint() should
generally not be used at all outside of an _eval_expand_hint() method.
If you want to apply a specific expansion from within another method, use
the public expand() function, method, or expand_hint() functions.
In order for expand to work, objects must be rebuildable by their args,
i.e., obj.func(*obj.args)==obj must hold.
Expand methods are passed **hints so that expand hints may use
‘metahints’–hints that control how different expand methods are applied.
For example, the force=True hint described above that causes
expand(log=True) to ignore assumptions is such a metahint. The
deep meta-hint is handled exclusively by expand() and is not
passed to _eval_expand_hint() methods.
Note that expansion hints should generally be methods that perform some
kind of ‘expansion’. For hints that simply rewrite an expression, use the
.rewrite() API.
Examples
>>> from..importExpr,sympify>>> classMyClass(Expr):... def__new__(cls,*args):... args=sympify(args)... returnExpr.__new__(cls,*args)...... def_eval_expand_double(self,**hints):... '''... Doubles the args of MyClass....... If there more than four args, doubling is not performed,... unless force=True is also used (False by default).... '''... force=hints.pop('force',False)... ifnotforceandlen(self.args)>4:... returnself... returnself.func(*(self.args+self.args))...>>> a=MyClass(1,2,MyClass(3,4))>>> aMyClass(1, 2, MyClass(3, 4))>>> a.expand(double=True)MyClass(1, 2, MyClass(3, 4, 3, 4), 1, 2, MyClass(3, 4, 3, 4))>>> a.expand(double=True,deep=False)MyClass(1, 2, MyClass(3, 4), 1, 2, MyClass(3, 4))
Wrapper around expand that only uses the power_base hint.
See the expand docstring for more information.
A wrapper to expand(power_base=True) which separates a power with a base
that is a Mul into a product of powers, without performing any other
expansions, provided that assumptions about the power’s base and exponent
allow.
deep=False (default is True) will only apply to the top-level expression.
force=True (default is False) will cause the expansion to ignore
assumptions about the base and exponent. When False, the expansion will
only happen if the base is non-negative or the exponent is an integer.
If you had a list of objects to test the commutivity of
and you want the fuzzy_and logic applied, passing an
iterator will allow the commutativity to only be computed
as many times as necessary. With this list, False can be
returned after analyzing the first symbol:
Returns a canonical form of cls applied to arguments args.
The eval() method is called when the class cls is about to be
instantiated and it should return either some simplified instance
(possible of some other class), or if the class cls should be
unmodified, return None.
Return the tuple (c, args) where self is written as a Mul, m.
c should be a Rational multiplied by any factors of the Mul that are
independent of deps.
args should be a tuple of all other factors of m; args is empty
if self is a Number or if self is independent of deps (when given).
This should be used when you don’t know if self is a Mul or not but
you want to treat self as a Mul or if you want to process the
individual arguments of the tail of self as a Mul.
if you know self is a Mul and want only the head, use self.args[0];
if you don’t want to process the arguments of the tail but need the
tail then use self.as_two_terms() which gives the head and tail;
if you want to split self into an independent and dependent parts
use self.as_independent(*deps)
Return a dictionary mapping terms to their coefficient.
Since the dictionary is a defaultdict, inquiries about terms which
were not present will return a coefficient of 0. The dictionary
is considered to have a single term.
Return self as a dictionary of factors with each factor being
treated as a power. The keys are the bases of the factors and the
values, the corresponding exponents. The resulting dictionary should
be used with caution if the expression is a Mul and contains non-
commutative factors since the order that they appeared will be lost in
the dictionary.
Performs complex expansion on ‘self’ and returns a tuple
containing collected both real and imaginary parts. This
method can’t be confused with re() and im() functions,
which does not perform complex expansion at evaluation.
However it is possible to expand both re() and im()
functions and get exactly the same results as with
a single call to this function.
This is the most efficient way to get the head and tail of an
expression.
if you want only the head, use self.args[0];
if you want to process the arguments of the tail then use
self.as_coef_mul() which gives the head and a tuple containing
the arguments of the tail when treated as a Mul.
if you want the coefficient when self is treated as an Add
then use self.as_coeff_add()[0]
>>> from..importMul,sqrt>>> from..abcimportx,y,z>>> 2*(x+1)# this is the 2-arg Mul behavior2*x + 2>>> y*(x+1)*22*y*(x + 1)>>> 2*(x+1)*y# 2-arg result will be obtained firsty*(2*x + 2)>>> Mul(2,x+1,y)# all 3 args simultaneously processed2*y*(x + 1)>>> 2*((x+1)*y)# parentheses can control this behavior2*y*(x + 1)
Powers with compound bases may not find a single base to
combine with unless all arguments are processed at once.
Post-processing may be necessary in such cases.
{c.f. https://github.com/sympy/sympy/issues/5728}
If more than two terms are being multiplied then all the
previous terms will be re-processed for each new argument.
So if each of a, b and c were Mul
expression, then a*b*c (or building up the product
with *=) will process all the arguments of a and
b twice: once when a*b is computed and again when
c is multiplied.
Using Mul(a,b,c) will process all arguments once.
The results of Mul are cached according to arguments, so flatten
will only be called once for Mul(a,b,c). If you can
structure a calculation so the arguments are most likely to be
repeats then this can save time in computing the answer. For
example, say you had a Mul, M, that you wished to divide by d[i]
and multiply by n[i] and you suspect there are many repeats
in n. It would be better to compute M*n[i]/d[i] rather
than M/d[i]*n[i] since every time n[i] is a repeat, the
product, M*n[i] will be returned without flattening – the
cached value will be returned. If you divide by the d[i]
first (and those are more unique than the n[i]) then that will
create a new Mul, M/d[i] the args of which will be traversed
again when it is multiplied by n[i].
The validity of the above notes depends on the implementation
details of Mul and flatten which may change at any time. Therefore,
you should only consider them when your code is highly performance
sensitive.
Removal of 1 from the sequence is already handled by AssocOp.__new__.
Returns a structure with the same dimension as the specified argument,
where each basic element is replaced by the function f applied on it. All
other arguments stay the same.
>>> vdiff([f(x,y,z),g(x,y,z),h(x,y,z)],[x,y,z])[[Derivative(f(x, y, z), x), Derivative(f(x, y, z), y), Derivative(f(x, y, z), z)], [Derivative(g(x, y, z), x), Derivative(g(x, y, z), y), Derivative(g(x, y, z), z)], [Derivative(h(x, y, z), x), Derivative(h(x, y, z), y), Derivative(h(x, y, z), z)]]
gamma = 0.5772157ldots (also called Euler’s constant) is a mathematical
constant recurring in analysis and number theory. It is defined as the
limiting difference between the harmonic series and the
natural logarithm:
The transcendental number e = 2.718281828ldots is the base of the
natural logarithm and of the exponential function, e = exp(1).
Sometimes called Euler’s number or Napier’s constant.
Exp1 is a singleton, and can be accessed by S.Exp1,
or can be imported as E.
Creating Floats from strings (and Python int and long
types) will give a minimum precision of 15 digits, but the
precision will automatically increase to capture all digits
entered.
It may be preferable to enter high-precision decimal numbers
as strings:
Float(‘1.23456789123456789’)
1.23456789123456789
The desired number of digits can also be specified:
>>> Float('1e-3',3)0.00100>>> Float(100,4)100.0
Float can automatically count significant figures if a null string
is sent for the precision; space are also allowed in the string. (Auto-
counting is only allowed for strings, ints and longs).
If a number is written in scientific notation, only the digits before the
exponent are considered significant if a decimal appears, otherwise the
“e” signifies only how to move the decimal:
Floats are inexact by their nature unless their value is a binary-exact
value.
>>> approx,exact=Float(.1,1),Float(.125,1)
For calculation purposes, evalf needs to be able to change the precision
but this will not increase the accuracy of the inexact value. The
following is the most accurate 5-digit approximation of a value of 0.1
that had only 1 digit of precision:
>>> approx.evalf(5)0.099609
By contrast, 0.125 is exact in binary (as it is in base 10) and so it
can be passed to Float or evalf to obtain an arbitrary precision with
matching accuracy:
Trying to make a high-precision Float from a float is not disallowed,
but one must keep in mind that the underlying float (not the apparent
decimal value) is being obtained with high precision. For example, 0.3
does not have a finite binary representation. The closest rational is
the fraction 5404319552844595/2**54. So if you try to obtain a Float of
0.3 to 20 digits of precision you will not see the same thing as 0.3
followed by 19 zeros:
>>> Float(0.3,20)0.29999999999999998890
If you want a 20-digit value of the decimal 0.3 (not the floating point
approximation of 0.3) you should send the 0.3 as a string. The underlying
representation is still binary but a higher precision than Python’s float
is used:
>>> Float('0.3',20)0.30000000000000000000
Although you can increase the precision of an existing Float using Float
it will not increase the accuracy – the underlying value is not changed:
>>> defshow(f):# binary rep of Float... from..importMul,Pow... s,m,e,b=f._mpf_... v=Mul(int(m),Pow(2,int(e),evaluate=False),evaluate=False)... print('%s at prec=%s'%(v,f._prec))...>>> t=Float('0.3',3)>>> show(t)4915/2**14 at prec=13>>> show(Float(t,20))# higher prec, not higher accuracy4915/2**14 at prec=70>>> show(Float(t,2))# lower prec307/2**10 at prec=10
The same thing happens when evalf is used on a Float:
>>> show(t.evalf(20))4915/2**14 at prec=70>>> show(t.evalf(2))307/2**10 at prec=10
Finally, Floats can be instantiated with an mpf tuple (n, c, p) to
produce the number (-1)**n*c*2**p:
An actual mpf tuple also contains the number of bits in c as the last
element of the tuple:
>>> _._mpf_(1, 5, 0, 3)
This is not needed for instantiation and is not the same thing as the
precision. The mpf tuple and the precision are two separate quantities
that Float tracks.
phi = frac{1 + sqrt{5}}{2} is algebraic number. Two quantities
are in the golden ratio if their ratio is the same as the ratio of
their sum to the larger of the two quantities, i.e. their maximum.
GoldenRatio is a singleton, and can be accessed by S.GoldenRatio.
In real analysis the symbol infty denotes an unbounded
limit: xtoinfty means that x grows without bound.
Infinity is often used not only to define a limit but as a value
in the affinely extended real number system. Points labeled +infty
and -infty can be added to the topological space of the real numbers,
producing the two-point compactification of the real numbers. Adding
algebraic properties to this gives us the extended real numbers.
Infinity is a singleton, and can be accessed by S.Infinity,
or can be imported as oo.
Returns True when the argument x is true, False otherwise.
The builtins True and False are the only two instances of the class bool.
The class bool is a subclass of the class int, and cannot be subclassed.
Returns True when the argument x is true, False otherwise.
The builtins True and False are the only two instances of the class bool.
The class bool is a subclass of the class int, and cannot be subclassed.
Returns True when the argument x is true, False otherwise.
The builtins True and False are the only two instances of the class bool.
The class bool is a subclass of the class int, and cannot be subclassed.
Returns True when the argument x is true, False otherwise.
The builtins True and False are the only two instances of the class bool.
The class bool is a subclass of the class int, and cannot be subclassed.
Returns True when the argument x is true, False otherwise.
The builtins True and False are the only two instances of the class bool.
The class bool is a subclass of the class int, and cannot be subclassed.
Returns True when the argument x is true, False otherwise.
The builtins True and False are the only two instances of the class bool.
The class bool is a subclass of the class int, and cannot be subclassed.
This serves as a place holder for numeric values that are indeterminate.
Most operations on NaN, produce another NaN. Most indeterminate forms,
such as 0/0 or oo-oo`produceNaN.Twoexceptionsare``0**0
and oo**0, which all produce 1 (this is consistent with Python’s
float).
NaN is loosely related to floating point nan, which is defined in the
IEEE 754 floating point standard, and corresponds to the Python
float('nan'). Differences are noted below.
NaN is mathematically not equal to anything else, even NaN itself. This
explains the initially counter-intuitive results with Eq and == in
the examples below.
NaN is not comparable so inequalities raise a TypeError. This is in
constrast with floating point nan where all inequalities are false.
NaN is a singleton, and can be accessed by S.NaN, or can be imported
as nan.
Floating point numbers are represented by the Float class.
Integer numbers (of any size), together with rational numbers (again,
there is no limit on their size) are represented by the Rational class.
If you want to represent, for example, 1+sqrt(2), then you need to do:
Return the tuple (c, args) where self is written as an Add, a.
c should be a Rational added to any terms of the Add that are
independent of deps.
args should be a tuple of all other terms of a; args is empty
if self is a Number or if self is independent of deps (when given).
This should be used when you don’t know if self is an Add or not but
you want to treat self as an Add or if you want to process the
individual arguments of the tail of self as an Add.
if you know self is an Add and want only the head, use self.args[0];
if you don’t want to process the arguments of the tail but need the
tail then use self.as_two_terms() which gives the head and tail.
if you want to split self into an independent and dependent parts
use self.as_independent(*deps)
Return the tuple (c, args) where self is written as a Mul, m.
c should be a Rational multiplied by any factors of the Mul that are
independent of deps.
args should be a tuple of all other factors of m; args is empty
if self is a Number or if self is independent of deps (when given).
This should be used when you don’t know if self is a Mul or not but
you want to treat self as a Mul or if you want to process the
individual arguments of the tail of self as a Mul.
if you know self is a Mul and want only the head, use self.args[0];
if you don’t want to process the arguments of the tail but need the
tail then use self.as_two_terms() which gives the head and tail;
if you want to split self into an independent and dependent parts
use self.as_independent(*deps)
Return True if self is constant, False if not, or None if
the constancy could not be determined conclusively.
If an expression has no free symbols then it is a constant. If
there are free symbols it is possible that the expression is a
constant, perhaps (but not necessarily) zero. To test such
expressions, two strategies are tried:
1) numerical evaluation at two random points. If two such evaluations
give two different values and the values have a precision greater than
1 then self is not constant. If the evaluations agree or could not be
obtained with any precision, no decision is made. The numerical testing
is done only if wrt is different than the free symbols.
2) differentiation with respect to variables in ‘wrt’ (or all free
symbols if omitted) to see if the expression is constant or not. This
will not always lead to an expression that is zero even though an
expression is constant (see added test in test_expr.py). If
all derivatives are zero then self is constant with respect to the
given symbols.
If neither evaluation nor differentiation can prove the expression is
constant, None is returned unless two numerical values happened to be
the same and the flag failing_number is True – in that case the
numerical value will be returned.
If flag simplify=False is passed, self will not be simplified;
the default is True since self should be simplified before testing.
>>> (0**x).is_constant()False>>> x.is_constant()False>>> (x**x).is_constant()False>>> one=cos(x)**2+sin(x)**2>>> one.is_constant()True>>> ((one-1)**(x+1)).is_constant()in(True,False)# could be 0 or 1True
A wrapper to factorint which return factors of self that are
smaller than limit (or cheap to compute). Special methods of
factoring are disabled by default so that only trial division is used.
The transcendental number pi = 3.141592654ldots represents the ratio
of a circle’s circumference to its diameter, the area of the unit circle,
the half-period of trigonometric functions, and many other things
in mathematics.
Pi is a singleton, and can be accessed by S.Pi, or can
be imported as pi.
If the simpler representation of the float is desired then consider
limiting the denominator to the desired value or convert the float to
a string (which is roughly equivalent to limiting the denominator to
10**12):
The conversion of other types of strings can be handled by
the sympify() function, and conversion of floats to expressions
or simple fractions can be handled with nsimplify:
>>> S('.[3]')# repeating digits in brackets1/3>>> S('3**2/10')# general expressions9/10>>> nsimplify(.3)# numbers that have a simple form3/10
But if the input does not reduce to a literal Rational, an error will
be raised:
>>> Rational(pi)Traceback (most recent call last):...TypeError: invalid input: pi
A wrapper to factorint which return factors of self that are
smaller than limit (or cheap to compute). Special methods of
factoring are disabled by default so that only trial division is used.
Return a bool indicating whether the error between z1 and z2 is <= tol.
If tol is None then True will be returned if there is a significant
difference between the numbers: abs(z1-z2)*10**p<=1/2 where p
is the lower of the precisions of the values. A comparison of strings will
be made if z1 is a Number and a) z2 is a string or b) tol is ‘’
and z2 is a Number.
When tol is a nonzero value, if z2 is non-zero and |z1|>1
the error is normalized by |z1|, so if you want to see if the
absolute error between z1 and z2 is <= tol then call this
as comp(z1-z2,0,tol).
Euclid’s algorithm for the computation of the greatest
common divisor gcd(a, b) of two (positive) integers
a and b is based on the division identity
a = q*b + r,
where the quotient q and the remainder r are integers
and 0 <= r < b. Then each common divisor of a and b
divides r, and it follows that gcd(a, b) == gcd(b, r).
The algorithm works by constructing the sequence
r0, r1, r2, …, where r0 = a, r1 = b, and each rn
is the remainder from the division of the two preceding
elements.
In Python, q = a // b and r = a % b are obtained by the
floor division and the remainder operations, respectively.
These are the most expensive arithmetic operations, especially
for large a and b.
Lehmer’s algorithm is based on the observation that the quotients
qn = r(n-1) // rn are in general small integers even
when a and b are very large. Hence the quotients can be
usually determined from a relatively small number of most
significant bits.
The efficiency of the algorithm is further enhanced by not
computing each long remainder in Euclid’s sequence. The remainders
are linear combinations of a and b with integer coefficients
derived from the quotients. The coefficients can be computed
as far as the quotients can be determined from the chosen
most significant parts of a and b. Only then a new pair of
consecutive remainders is computed and the algorithm starts
anew with this pair.
Suppose we wish to find multiplicative inverse x of
3 modulo 11. This is the same as finding x such
that 3 * x = 1 (mod 11). One value of x that satisfies
this congruence is 4. Because 3 * 4 = 12 and 12 = 1 mod(11).
This is the value return by mod_inverse:
>>> mod_inverse(3,11)4>>> mod_inverse(-3,11)-4
When there is a common factor between the numerators of
a and m the inverse does not exist:
>>> mod_inverse(2,4)Traceback (most recent call last):...ValueError: inverse of 2 mod 4 does not exist
Return the mpf tuple normalized appropriately for the indicated
precision after doing a check to see if zero should be returned or
not when the mantissa is 0. mpf_normlize always assumes that this
is zero, but it may not be since the mantissa for mpf’s values “+inf”,
“-inf” and “nan” have a mantissa of zero, too.
Note: this is not intended to validate a given mpf tuple, so sending
mpf tuples that were not created by mpmath may produce bad results. This
is only a wrapper to mpf_normalize which provides the check for non-
zero mpfs that have a 0 for the mantissa.
Return seq so that none of the elements are of type cls. This is
the vanilla routine that will be used if a class derived from AssocOp
does not define its own flatten routine.
These binary operations are associative (op(op(a, b), c) = op(a, op(b, c))),
commutative (op(a, b) = op(b, a)) and idempotent (op(a, a) = op(a) = a).
Common examples are AND, OR, Union, Intersection, max or min. They have an
identity element (op(identity, a) = a) and an absorbing element
conventionally called zero (op(zero, a) = zero).
This is an abstract base class, concrete derived classes must declare
attributes zero and identity. All defining properties are then respected.
Never use self._args, always use self.args.
Only use _args in __new__ when creating a new function.
Don’t override .args() from Basic (so that it’s easy to
change the interface in the future if needed).
Defines the expression x**y as “x raised to a power y”
Singleton definitions involving (0, 1, -1, oo, -oo, I, -I):
expr
value
reason
z**0
1
Although arguments over 0**0 exist, see [2].
z**1
z
(-oo)**(-1)
0
(-1)**-1
-1
S.Zero**-1
zoo
This is not strictly true, as 0**-1 may be
undefined, but is convenient in some contexts
where the base is assumed to be positive.
1**-1
1
oo**-1
0
0**oo
0
Because for all complex numbers z near
0, z**oo -> 0.
0**-oo
zoo
This is not strictly true, as 0**oo may be
oscillating between positive and negative
values or rotating in the complex plane.
It is convenient, however, when the base
is positive.
1**oo
1**-oo
1**zoo
nan
Because there are various cases where
lim(x(t),t)=1, lim(y(t),t)=oo (or -oo),
but lim( x(t)**y(t), t) != 1. See [3].
(-1)**oo
(-1)**(-oo)
nan
Because of oscillations in the limit.
oo**oo
oo
oo**-oo
0
(-oo)**oo
(-oo)**-oo
nan
oo**I
(-oo)**I
nan
oo**e could probably be best thought of as
the limit of x**e for real x as x tends to
oo. If e is I, then the limit does not exist
and nan is used to indicate that.
oo**(1+I)
(-oo)**(1+I)
zoo
If the real part of e is positive, then the
limit of abs(x**e) is oo. So the limit value
is zoo.
oo**(-1+I)
-oo**(-1+I)
0
If the real part of e is negative, then the
limit is 0.
Because symbolic computations are more flexible that floating point
calculations and we prefer to never return an incorrect answer,
we choose not to conform to all IEEE 754 conventions. This helps
us avoid extra test-case code in the calculation of limits.
Performs complex expansion on ‘self’ and returns a tuple
containing collected both real and imaginary parts. This
method can’t be confused with re() and im() functions,
which does not perform complex expansion at evaluation.
However it is possible to expand both re() and im()
functions and get exactly the same results as with
a single call to this function.
Return True if self is constant, False if not, or None if
the constancy could not be determined conclusively.
If an expression has no free symbols then it is a constant. If
there are free symbols it is possible that the expression is a
constant, perhaps (but not necessarily) zero. To test such
expressions, two strategies are tried:
1) numerical evaluation at two random points. If two such evaluations
give two different values and the values have a precision greater than
1 then self is not constant. If the evaluations agree or could not be
obtained with any precision, no decision is made. The numerical testing
is done only if wrt is different than the free symbols.
2) differentiation with respect to variables in ‘wrt’ (or all free
symbols if omitted) to see if the expression is constant or not. This
will not always lead to an expression that is zero even though an
expression is constant (see added test in test_expr.py). If
all derivatives are zero then self is constant with respect to the
given symbols.
If neither evaluation nor differentiation can prove the expression is
constant, None is returned unless two numerical values happened to be
the same and the flag failing_number is True – in that case the
numerical value will be returned.
If flag simplify=False is passed, self will not be simplified;
the default is True since self should be simplified before testing.
>>> (0**x).is_constant()False>>> x.is_constant()False>>> (x**x).is_constant()False>>> one=cos(x)**2+sin(x)**2>>> one.is_constant()True>>> ((one-1)**(x+1)).is_constant()in(True,False)# could be 0 or 1True
Represents that two objects are equal. If they can be easily shown
to be definitively equal (or unequal), this will reduce to True (or
False). Otherwise, the relation is maintained as an unevaluated
Equality object. Use the simplify function on this object for
more nontrivial evaluation of the equality relation.
As usual, the keyword argument evaluate=False can be used to
prevent any evaluation.
for representing equality between two boolean expressions
Notes
This class is not the same as the == operator. The == operator tests
for exact structural equality between two expressions; this class
compares expressions mathematically.
If either object defines an _eval_Eq method, it can be used in place of
the default algorithm. If lhs._eval_Eq(rhs) or rhs._eval_Eq(lhs)
returns anything other than None, that return value will be substituted for
the Equality. If None is returned by _eval_Eq, an Equality object will
be created as usual.
The *Than classes represent inequal relationships, where the left-hand
side is generally bigger or smaller than the right-hand side. For example,
the GreaterThan class represents an inequal relationship where the
left-hand side is at least as big as the right side, if not bigger. In
mathematical notation:
lhs >= rhs
In total, there are four *Than classes, to represent the four
inequalities:
Class Name
Symbol
GreaterThan
(>=)
LessThan
(<=)
StrictGreaterThan
(>)
StrictLessThan
(<)
All classes take two arguments, lhs and rhs.
Signature Example
Math equivalent
GreaterThan(lhs, rhs)
lhs >= rhs
LessThan(lhs, rhs)
lhs <= rhs
StrictGreaterThan(lhs, rhs)
lhs > rhs
StrictLessThan(lhs, rhs)
lhs < rhs
In addition to the normal .lhs and .rhs of Relations, *Than inequality
objects also have the .lts and .gts properties, which represent the “less
than side” and “greater than side” of the operator. Use of .lts and .gts
in an algorithm rather than .lhs and .rhs as an assumption of inequality
direction will make more explicit the intent of a certain section of code,
and will make it similarly more robust to client code changes:
Another option is to use the Python inequality operators (>=, >, <=, <)
directly. Their main advantage over the Ge, Gt, Le, and Lt counterparts, is
that one can write a more “mathematical looking” statement rather than
littering the math with oddball function calls. However there are certain
(minor) caveats of which to be aware (search for ‘gotcha’, below).
>>> e2=x>=2>>> print(e2)x >= 2>>> print("e1: %s, e2: %s"%(e1,e2))e1: x >= 2, e2: x >= 2>>> e1==e2True
However, it is also perfectly valid to instantiate a *Than class less
succinctly and less conveniently:
There are a couple of “gotchas” when using Python’s operators.
The first enters the mix when comparing against a literal number as the lhs
argument. Due to the order that Python decides to parse a statement, it may
not immediately find two objects comparable. For example, to evaluate the
statement (1 < x), Python will first recognize the number 1 as a native
number, and then that x is not a native number. At this point, because a
native Python number does not know how to compare itself with a SymPy object
Python will try the reflective operation, (x > 1). Unfortunately, there is
no way available to SymPy to recognize this has happened, so the statement
(1 < x) will turn silently into (x > 1).
>>> e1=x>1>>> e2=x>=1>>> e3=x<1>>> e4=x<=1>>> e5=1>x>>> e6=1>=x>>> e7=1<x>>> e8=1<=x>>> print("%s%s\n"*4%(e1,e2,e3,e4,e5,e6,e7,e8))x > 1 x >= 1x < 1 x <= 1x < 1 x <= 1x > 1 x >= 1
If the order of the statement is important (for visual output to the
console, perhaps), one can work around this annoyance in a couple ways: (1)
“sympify” the literal before comparison, (2) use one of the wrappers, or (3)
use the less succinct methods described above:
>>> e1=S(1)>x>>> e2=S(1)>=x>>> e3=S(1)<x>>> e4=S(1)<=x>>> e5=Gt(1,x)>>> e6=Ge(1,x)>>> e7=Lt(1,x)>>> e8=Le(1,x)>>> print("%s%s\n"*4%(e1,e2,e3,e4,e5,e6,e7,e8))1 > x 1 >= x1 < x 1 <= x1 > x 1 >= x1 < x 1 <= x
The other gotcha is with chained inequalities. Occasionally, one may be
tempted to write statements like:
>>> e=x<y<zTraceback (most recent call last):...TypeError: symbolic boolean expression has no truth value.
Due to an implementation detail or decision of Python [1]_, there is no way
for SymPy to reliably create that as a chained inequality. To create a
chained inequality, the only method currently available is to make use of
And:
Note that this is different than chaining an equality directly via use of
parenthesis (this is currently an open bug in SymPy [2]_):
>>> e=(x<y)<z>>> type(e)<class 'sympy.core.relational.StrictLessThan'>>>> e(x < y) < z
Any code that explicitly relies on this latter functionality will not be
robust as this behaviour is completely wrong and will be corrected at some
point. For the time being (circa Jan 2012), use And to create chained
inequalities.
The *Than classes represent inequal relationships, where the left-hand
side is generally bigger or smaller than the right-hand side. For example,
the GreaterThan class represents an inequal relationship where the
left-hand side is at least as big as the right side, if not bigger. In
mathematical notation:
lhs >= rhs
In total, there are four *Than classes, to represent the four
inequalities:
Class Name
Symbol
GreaterThan
(>=)
LessThan
(<=)
StrictGreaterThan
(>)
StrictLessThan
(<)
All classes take two arguments, lhs and rhs.
Signature Example
Math equivalent
GreaterThan(lhs, rhs)
lhs >= rhs
LessThan(lhs, rhs)
lhs <= rhs
StrictGreaterThan(lhs, rhs)
lhs > rhs
StrictLessThan(lhs, rhs)
lhs < rhs
In addition to the normal .lhs and .rhs of Relations, *Than inequality
objects also have the .lts and .gts properties, which represent the “less
than side” and “greater than side” of the operator. Use of .lts and .gts
in an algorithm rather than .lhs and .rhs as an assumption of inequality
direction will make more explicit the intent of a certain section of code,
and will make it similarly more robust to client code changes:
Another option is to use the Python inequality operators (>=, >, <=, <)
directly. Their main advantage over the Ge, Gt, Le, and Lt counterparts, is
that one can write a more “mathematical looking” statement rather than
littering the math with oddball function calls. However there are certain
(minor) caveats of which to be aware (search for ‘gotcha’, below).
>>> e2=x>=2>>> print(e2)x >= 2>>> print("e1: %s, e2: %s"%(e1,e2))e1: x >= 2, e2: x >= 2>>> e1==e2True
However, it is also perfectly valid to instantiate a *Than class less
succinctly and less conveniently:
There are a couple of “gotchas” when using Python’s operators.
The first enters the mix when comparing against a literal number as the lhs
argument. Due to the order that Python decides to parse a statement, it may
not immediately find two objects comparable. For example, to evaluate the
statement (1 < x), Python will first recognize the number 1 as a native
number, and then that x is not a native number. At this point, because a
native Python number does not know how to compare itself with a SymPy object
Python will try the reflective operation, (x > 1). Unfortunately, there is
no way available to SymPy to recognize this has happened, so the statement
(1 < x) will turn silently into (x > 1).
>>> e1=x>1>>> e2=x>=1>>> e3=x<1>>> e4=x<=1>>> e5=1>x>>> e6=1>=x>>> e7=1<x>>> e8=1<=x>>> print("%s%s\n"*4%(e1,e2,e3,e4,e5,e6,e7,e8))x > 1 x >= 1x < 1 x <= 1x < 1 x <= 1x > 1 x >= 1
If the order of the statement is important (for visual output to the
console, perhaps), one can work around this annoyance in a couple ways: (1)
“sympify” the literal before comparison, (2) use one of the wrappers, or (3)
use the less succinct methods described above:
>>> e1=S(1)>x>>> e2=S(1)>=x>>> e3=S(1)<x>>> e4=S(1)<=x>>> e5=Gt(1,x)>>> e6=Ge(1,x)>>> e7=Lt(1,x)>>> e8=Le(1,x)>>> print("%s%s\n"*4%(e1,e2,e3,e4,e5,e6,e7,e8))1 > x 1 >= x1 < x 1 <= x1 > x 1 >= x1 < x 1 <= x
The other gotcha is with chained inequalities. Occasionally, one may be
tempted to write statements like:
>>> e=x<y<zTraceback (most recent call last):...TypeError: symbolic boolean expression has no truth value.
Due to an implementation detail or decision of Python [1]_, there is no way
for SymPy to reliably create that as a chained inequality. To create a
chained inequality, the only method currently available is to make use of
And:
Note that this is different than chaining an equality directly via use of
parenthesis (this is currently an open bug in SymPy [2]_):
>>> e=(x<y)<z>>> type(e)<class 'sympy.core.relational.StrictLessThan'>>>> e(x < y) < z
Any code that explicitly relies on this latter functionality will not be
robust as this behaviour is completely wrong and will be corrected at some
point. For the time being (circa Jan 2012), use And to create chained
inequalities.
Subclasses of Relational should generally be instantiated directly, but
Relational can be instantiated with a valid rop value to dispatch to
the appropriate subclass.
Parameters:
rop (str or None) – Indicates what subclass to instantiate. Valid values can be found
in the keys of Relational.ValidRelationalOperator.
Return True if the sides of the relationship are mathematically
identical and the type of relationship is the same.
If failing_expression is True, return the expression whose truth value
was unknown.
The *Than classes represent inequal relationships, where the left-hand
side is generally bigger or smaller than the right-hand side. For example,
the GreaterThan class represents an inequal relationship where the
left-hand side is at least as big as the right side, if not bigger. In
mathematical notation:
lhs >= rhs
In total, there are four *Than classes, to represent the four
inequalities:
Class Name
Symbol
GreaterThan
(>=)
LessThan
(<=)
StrictGreaterThan
(>)
StrictLessThan
(<)
All classes take two arguments, lhs and rhs.
Signature Example
Math equivalent
GreaterThan(lhs, rhs)
lhs >= rhs
LessThan(lhs, rhs)
lhs <= rhs
StrictGreaterThan(lhs, rhs)
lhs > rhs
StrictLessThan(lhs, rhs)
lhs < rhs
In addition to the normal .lhs and .rhs of Relations, *Than inequality
objects also have the .lts and .gts properties, which represent the “less
than side” and “greater than side” of the operator. Use of .lts and .gts
in an algorithm rather than .lhs and .rhs as an assumption of inequality
direction will make more explicit the intent of a certain section of code,
and will make it similarly more robust to client code changes:
Another option is to use the Python inequality operators (>=, >, <=, <)
directly. Their main advantage over the Ge, Gt, Le, and Lt counterparts, is
that one can write a more “mathematical looking” statement rather than
littering the math with oddball function calls. However there are certain
(minor) caveats of which to be aware (search for ‘gotcha’, below).
>>> e2=x>=2>>> print(e2)x >= 2>>> print("e1: %s, e2: %s"%(e1,e2))e1: x >= 2, e2: x >= 2>>> e1==e2True
However, it is also perfectly valid to instantiate a *Than class less
succinctly and less conveniently:
There are a couple of “gotchas” when using Python’s operators.
The first enters the mix when comparing against a literal number as the lhs
argument. Due to the order that Python decides to parse a statement, it may
not immediately find two objects comparable. For example, to evaluate the
statement (1 < x), Python will first recognize the number 1 as a native
number, and then that x is not a native number. At this point, because a
native Python number does not know how to compare itself with a SymPy object
Python will try the reflective operation, (x > 1). Unfortunately, there is
no way available to SymPy to recognize this has happened, so the statement
(1 < x) will turn silently into (x > 1).
>>> e1=x>1>>> e2=x>=1>>> e3=x<1>>> e4=x<=1>>> e5=1>x>>> e6=1>=x>>> e7=1<x>>> e8=1<=x>>> print("%s%s\n"*4%(e1,e2,e3,e4,e5,e6,e7,e8))x > 1 x >= 1x < 1 x <= 1x < 1 x <= 1x > 1 x >= 1
If the order of the statement is important (for visual output to the
console, perhaps), one can work around this annoyance in a couple ways: (1)
“sympify” the literal before comparison, (2) use one of the wrappers, or (3)
use the less succinct methods described above:
>>> e1=S(1)>x>>> e2=S(1)>=x>>> e3=S(1)<x>>> e4=S(1)<=x>>> e5=Gt(1,x)>>> e6=Ge(1,x)>>> e7=Lt(1,x)>>> e8=Le(1,x)>>> print("%s%s\n"*4%(e1,e2,e3,e4,e5,e6,e7,e8))1 > x 1 >= x1 < x 1 <= x1 > x 1 >= x1 < x 1 <= x
The other gotcha is with chained inequalities. Occasionally, one may be
tempted to write statements like:
>>> e=x<y<zTraceback (most recent call last):...TypeError: symbolic boolean expression has no truth value.
Due to an implementation detail or decision of Python [1]_, there is no way
for SymPy to reliably create that as a chained inequality. To create a
chained inequality, the only method currently available is to make use of
And:
Note that this is different than chaining an equality directly via use of
parenthesis (this is currently an open bug in SymPy [2]_):
>>> e=(x<y)<z>>> type(e)<class 'sympy.core.relational.StrictLessThan'>>>> e(x < y) < z
Any code that explicitly relies on this latter functionality will not be
robust as this behaviour is completely wrong and will be corrected at some
point. For the time being (circa Jan 2012), use And to create chained
inequalities.
The *Than classes represent inequal relationships, where the left-hand
side is generally bigger or smaller than the right-hand side. For example,
the GreaterThan class represents an inequal relationship where the
left-hand side is at least as big as the right side, if not bigger. In
mathematical notation:
lhs >= rhs
In total, there are four *Than classes, to represent the four
inequalities:
Class Name
Symbol
GreaterThan
(>=)
LessThan
(<=)
StrictGreaterThan
(>)
StrictLessThan
(<)
All classes take two arguments, lhs and rhs.
Signature Example
Math equivalent
GreaterThan(lhs, rhs)
lhs >= rhs
LessThan(lhs, rhs)
lhs <= rhs
StrictGreaterThan(lhs, rhs)
lhs > rhs
StrictLessThan(lhs, rhs)
lhs < rhs
In addition to the normal .lhs and .rhs of Relations, *Than inequality
objects also have the .lts and .gts properties, which represent the “less
than side” and “greater than side” of the operator. Use of .lts and .gts
in an algorithm rather than .lhs and .rhs as an assumption of inequality
direction will make more explicit the intent of a certain section of code,
and will make it similarly more robust to client code changes:
Another option is to use the Python inequality operators (>=, >, <=, <)
directly. Their main advantage over the Ge, Gt, Le, and Lt counterparts, is
that one can write a more “mathematical looking” statement rather than
littering the math with oddball function calls. However there are certain
(minor) caveats of which to be aware (search for ‘gotcha’, below).
>>> e2=x>=2>>> print(e2)x >= 2>>> print("e1: %s, e2: %s"%(e1,e2))e1: x >= 2, e2: x >= 2>>> e1==e2True
However, it is also perfectly valid to instantiate a *Than class less
succinctly and less conveniently:
There are a couple of “gotchas” when using Python’s operators.
The first enters the mix when comparing against a literal number as the lhs
argument. Due to the order that Python decides to parse a statement, it may
not immediately find two objects comparable. For example, to evaluate the
statement (1 < x), Python will first recognize the number 1 as a native
number, and then that x is not a native number. At this point, because a
native Python number does not know how to compare itself with a SymPy object
Python will try the reflective operation, (x > 1). Unfortunately, there is
no way available to SymPy to recognize this has happened, so the statement
(1 < x) will turn silently into (x > 1).
>>> e1=x>1>>> e2=x>=1>>> e3=x<1>>> e4=x<=1>>> e5=1>x>>> e6=1>=x>>> e7=1<x>>> e8=1<=x>>> print("%s%s\n"*4%(e1,e2,e3,e4,e5,e6,e7,e8))x > 1 x >= 1x < 1 x <= 1x < 1 x <= 1x > 1 x >= 1
If the order of the statement is important (for visual output to the
console, perhaps), one can work around this annoyance in a couple ways: (1)
“sympify” the literal before comparison, (2) use one of the wrappers, or (3)
use the less succinct methods described above:
>>> e1=S(1)>x>>> e2=S(1)>=x>>> e3=S(1)<x>>> e4=S(1)<=x>>> e5=Gt(1,x)>>> e6=Ge(1,x)>>> e7=Lt(1,x)>>> e8=Le(1,x)>>> print("%s%s\n"*4%(e1,e2,e3,e4,e5,e6,e7,e8))1 > x 1 >= x1 < x 1 <= x1 > x 1 >= x1 < x 1 <= x
The other gotcha is with chained inequalities. Occasionally, one may be
tempted to write statements like:
>>> e=x<y<zTraceback (most recent call last):...TypeError: symbolic boolean expression has no truth value.
Due to an implementation detail or decision of Python [1]_, there is no way
for SymPy to reliably create that as a chained inequality. To create a
chained inequality, the only method currently available is to make use of
And:
Note that this is different than chaining an equality directly via use of
parenthesis (this is currently an open bug in SymPy [2]_):
>>> e=(x<y)<z>>> type(e)<class 'sympy.core.relational.StrictLessThan'>>>> e(x < y) < z
Any code that explicitly relies on this latter functionality will not be
robust as this behaviour is completely wrong and will be corrected at some
point. For the time being (circa Jan 2012), use And to create chained
inequalities.
Represents that two objects are not equal. If they can be shown to be
definitively equal, this will reduce to False; if definitively unequal,
this will reduce to True. Otherwise, the relation is maintained as an
Unequality object.
This class is not the same as the != operator. The != operator tests
for exact structural equality between two expressions; this class
compares expressions mathematically.
This class is effectively the inverse of Equality. As such, it uses the
same algorithms, including any available _eval_Eq methods.
By default, all values are considered to be in the dictionary. If a filter
is supplied, only the objects for which it returns True are considered as
being in the dictionary:
A singleton class has only one instance which is returned every time the
class is instantiated. Additionally, this instance can be accessed through
the global registry object S as S.<class_name>.
Instance creation is delayed until the first time the value is accessed.
(SymPy versions before 1.0 would create the instance during class
creation time, which would be prone to import cycles.)
This metaclass is a subclass of ManagedProperties because that is the
metaclass of many classes that need to be Singletons (Python does not allow
subclasses to have a different metaclass than the superclass, except the
subclass may use a subclassed metaclass).
The registry for the singleton classes (accessible as S).
This class serves as two separate things.
The first thing it is is the SingletonRegistry. Several classes in
SymPy appear so often that they are singletonized, that is, using some
metaprogramming they are made so that they can only be instantiated once
(see the sympy.core.singleton.Singleton class for details). For
instance, every time you create Integer(0), this will return the same
instance, sympy.core.numbers.Zero. All singleton instances are
attributes of the S object, so Integer(0) can also be accessed as
S.Zero.
Singletonization offers two advantages: it saves memory, and it allows
fast comparison. It saves memory because no matter how many times the
singletonized objects appear in expressions in memory, they all point to
the same single instance in memory. The fast comparison comes from the
fact that you can use is to compare exact instances in Python
(usually, you need to use == to compare things). is compares
objects by memory address, and is very fast. For instance
For the most part, the fact that certain objects are singletonized is an
implementation detail that users shouldn’t need to worry about. In SymPy
library code, is comparison is often used for performance purposes
The primary advantage of S for end users is the convenient access to
certain instances that are otherwise difficult to type, like S.Half
(instead of Rational(1,2)).
When using is comparison, make sure the argument is sympified. For
instance,
>>> 0isS.ZeroFalse
This problem is not an issue when using ==, which is recommended for
most use-cases:
>>> 0==S.ZeroTrue
The second thing S is is a shortcut for
sympy.core.sympify.sympify(). sympy.core.sympify.sympify() is
the function that converts Python objects such as int(1) into SymPy
objects such as Integer(1). It also converts the string form of an
expression into a SymPy expression, like sympify("x**2") ->
Symbol("x")**2. S(1) is the same thing as sympify(1)
(basically, S.__call__ has been defined to call sympify).
This is for convenience, since S is a single letter. It’s mostly
useful for defining rational numbers. Consider an expression like x+1/2. If you enter this directly in Python, it will evaluate the 1/2
and give 0.5 (or just 0 in Python 2, because of integer division),
because both arguments are ints (see also
tutorial-gotchas-final-notes). However, in SymPy, you usually want
the quotient of two integers to give an exact rational number. The way
Python’s evaluation works, at least one side of an operator needs to be a
SymPy object for the SymPy evaluation to take over. You could write this
as x+Rational(1,2), but this is a lot more typing. A shorter
version is x+S(1)/2. Since S(1) returns Integer(1), the
division will return a Rational type, since it will call
Integer.__div__, which knows how to return a Rational.
If a name is not supplied then a string value of an internal count will be
used. This is useful when a temporary variable is needed and the name
of the variable used in the expression is not important.
You can override the default assumptions in the constructor:
>>> from..importsymbols>>> A,B=symbols('A,B',commutative=False)>>> bool(A*B!=B*A)True>>> bool(A*B*2==2*A*B)==True# multiplication by scalars is commutativeTrue
Performs complex expansion on ‘self’ and returns a tuple
containing collected both real and imaginary parts. This
method can’t be confused with re() and im() functions,
which does not perform complex expansion at evaluation.
However it is possible to expand both re() and im()
functions and get exactly the same results as with
a single call to this function.
Return from the atoms of self those which are free symbols.
For most expressions, all symbols are free symbols. For some classes
this is not true. e.g. Integrals use Symbols for the dummy variables
which are bound variables, so Integral has a method to return all
symbols except those. Derivative keeps track of symbols with respect
to which it will perform a derivative; those are
bound variables, too, so it has its own free_symbols method.
Any other method that uses bound variables should implement a
free_symbols method.
Return True if self is constant, False if not, or None if
the constancy could not be determined conclusively.
If an expression has no free symbols then it is a constant. If
there are free symbols it is possible that the expression is a
constant, perhaps (but not necessarily) zero. To test such
expressions, two strategies are tried:
1) numerical evaluation at two random points. If two such evaluations
give two different values and the values have a precision greater than
1 then self is not constant. If the evaluations agree or could not be
obtained with any precision, no decision is made. The numerical testing
is done only if wrt is different than the free symbols.
2) differentiation with respect to variables in ‘wrt’ (or all free
symbols if omitted) to see if the expression is constant or not. This
will not always lead to an expression that is zero even though an
expression is constant (see added test in test_expr.py). If
all derivatives are zero then self is constant with respect to the
given symbols.
If neither evaluation nor differentiation can prove the expression is
constant, None is returned unless two numerical values happened to be
the same and the flag failing_number is True – in that case the
numerical value will be returned.
If flag simplify=False is passed, self will not be simplified;
the default is True since self should be simplified before testing.
>>> (0**x).is_constant()False>>> x.is_constant()False>>> (x**x).is_constant()False>>> one=cos(x)**2+sin(x)**2>>> one.is_constant()True>>> ((one-1)**(x+1)).is_constant()in(True,False)# could be 0 or 1True
When using Wild, be sure to use the exclude
keyword to make the pattern more precise.
Without the exclude pattern, you may get matches
that are technically correct, but not what you
wanted. For example, using the above without
exclude:
This is technically correct, because
(2/x)*x + 3*y == 2 + 3*y, but you probably
wanted it to not match at all. The issue is that
you really didn’t want a and b to include x and y,
and the exclude parameter lets you specify exactly
this. With the exclude parameter, the pattern will
not match.
symbols() function returns a sequence of symbols with names taken
from names argument, which can be a comma or whitespace delimited
string, or a sequence of strings:
>>> from..importsymbols,Function>>> x,y,z=symbols('x,y,z')>>> a,b,c=symbols('a b c')
The type of output is dependent on the properties of input arguments:
If an iterable container is needed for a single symbol, set the seq
argument to True or terminate the symbol name with a comma:
>>> symbols('x',seq=True)(x,)
To reduce typing, range syntax is supported to create indexed symbols.
Ranges are indicated by a colon and the type of range is determined by
the character to the right of the colon. If the character is a digit
then all contiguous digits to the left are taken as the nonnegative
starting value (or 0 if there is no digit left of the colon) and all
contiguous digits to the right are taken as 1 greater than the ending
value:
If the character to the right of the colon is a letter, then the single
letter to the left (or ‘a’ if there is none) is taken as the start
and all characters in the lexicographic range through the letter to
the right are used as the range:
>>> symbols('x:z')(x, y, z)>>> symbols('x:c')# null range()>>> symbols('x(:c)')(xa, xb, xc)>>> symbols(':c')(a, b, c)>>> symbols('a:d, x:z')(a, b, c, d, x, y, z)>>> symbols(('a:d','x:z'))((a, b, c, d), (x, y, z))
Multiple ranges are supported; contiguous numerical ranges should be
separated by parentheses to disambiguate the ending number of one
range from the starting number of the next:
>>> symbols('x:2(1:3)')(x01, x02, x11, x12)>>> symbols(':3:2')# parsing is from left to right(00, 01, 10, 11, 20, 21)
Only one pair of parentheses surrounding ranges are removed, so to
include parentheses around ranges, double them. And to include spaces,
commas, or colons, escape them with a backslash:
>>> symbols('x((a:b))')(x(a), x(b))>>> symbols(r'x(:1\,:2)')# or r'x((:1)\,(:2))'(x(0,0), x(0,1))
All newly created symbols have assumptions set according to args:
Despite its name, symbols() can create symbol-like objects like
instances of Function or Wild classes. To achieve this, set cls
keyword argument to the desired type:
Create symbols and inject them into the global namespace.
This calls symbols() with the same arguments and puts the results
into the global namespace. It’s recommended not to use var() in
library code, where symbols() has to be used:
Use a hack to try keep autosimplification from joining Integer or
minus sign into an Add of a Mul; this modification doesn’t
prevent the 2-arg Mul from becoming an Add, however.
Converts an arbitrary expression to a type that can be used inside SymPy.
For example, it will convert Python ints into instance of sympy.Rational,
floats into instances of sympy.Float, etc. It is also able to coerce symbolic
expressions which inherit from Basic. This can be useful in cooperation
with SAGE.
It currently accepts as arguments:
any object defined in sympy
standard numeric python types: int, long, float, Decimal
strings (like “0.09” or “2e-19”)
booleans, including None (will leave None unchanged)
lists, sets or tuples containing any of the above
Warning
Note that this function uses eval, and thus shouldn’t be used on
unsanitized input.
If the argument is already a type that SymPy understands, it will do
nothing but return that value. This can be used at the beginning of a
function to ensure you are working with the correct type.
The sympification happens with access to everything that is loaded
by from..import*; anything used in a string that is not
defined by that import will be converted to a symbol. In the following,
the bitcount function is treated as a symbol and the O is
interpreted as the Order object (used with series) and it raises
an error when used improperly:
In order to have the O interpreted as a Symbol, identify it as such
in the namespace dictionary. This can be done in a variety of ways; all
three of the following are possibilities:
If you want all single-letter and Greek-letter variables to be symbols
then you can use the clashing-symbols dictionaries that have been defined
there as private variables: _clash1 (single-letter variables), _clash2
(the multi-letter Greek names) or _clash (both single and multi-letter
names that are defined in abc).
>>> from..abcimport_clash1>>> _clash1{'C': C, 'E': E, 'I': I, 'N': N, 'O': O, 'Q': Q, 'S': S}>>> sympify('I & Q',_clash1)I & Q
If the option strict is set to True, only the types for which an
explicit conversion has been defined are converted. In the other
cases, a SympifyError is raised.
If the option evaluate is set to False, then arithmetic and
operators will be converted into their SymPy equivalents and the
evaluate=False option will be added. Nested Add or Mul will
be denested first. This is done via an AST transformation that replaces
operators with their SymPy equivalents, so if an operand redefines any
of those operations, the redefined operators will not be used.
To extend sympify to convert custom objects (not derived from Basic),
just define a _sympy_ method to your class. You can do that even to
classes that you do not own by subclassing or adding the method at runtime.
If you do not have control over the class definition you could also use the
converter global dictionary. The key is the class and the value is a
function that takes a single argument and returns the desired SymPy
object, e.g. converter[MyList]=lambdax:Matrix(x).
>>> classMyList2(object):# XXX Do not do this if you control the class!... def__iter__(self):# Use _sympy_!... yield1... yield2... return... def__getitem__(self,i):returnlist(self)[i]>>> from.sympifyimportconverter>>> converter[MyList2]=lambdax:Matrix(x)>>> sympify(MyList2())Matrix([[1],[2]])
Notes
Sometimes autosimplification during sympification results in expressions
that are very different in structure than what was entered. Until such
autosimplification is no longer done, the kernS function might be of
some use. In the example below you can see how an expression reduces to
-1 by autosimplification, but does not do so when kernS is used.
Returns True if self has no free symbols.
It will be faster than ifnotself.free_symbols, however, since
is_number will fail as soon as it hits a free symbol.
pos (integer, if positive, shift-right, else shift-left) –
Examples
>>> from.traceimportTr>>> from..importsymbols>>> A,B,C,D=symbols('A B C D',commutative=False)>>> t=Tr(A*B*C*D)>>> t.permute(2)Tr(C*D*A*B)>>> t.permute(-2)Tr(C*D*A*B)