Check if a Sympy expression simplifies to a constant - sympy

Is there a way (within Sympy) to check if two expressions differ by a mere constant? In other words, is there something like a is_constant() function?
My minimum working example:
from sympy import symbols, simplify
x,y = symbols('x y')
expr1 = x+y+1
expr2 = x+y+3
if is_constant(simplify(expr1 - expr2)):
print('expr2 is just expr1 added to a constant!')

You could use the is_constant() method of Sympy objects. For example,
(expr1 - expr2).is_constant()
True

Related

sympy function compose - bizzare results

I'm trying to compose two functions and I get a bizzare result
'''
#!/usr/bin/python
from sympy import *
init_printing(use_unicode=True)
x= symbols('x')
f = x/(x+1);
g = x/(x+2);
print(compose(f,g))
This shows : x/((x + 1)*(x + 2))
Should be x/(2x+2)
I don't get it. Does anyone has an idea?
Thanks
Despite being available in the top-level sympy namespace under the plain name compose, sympy.compose doesn't actually do general function composition.
sympy.compose is actually sympy.polys.polytools.compose. It's actually a function for polynomial composition. When you try to compose x/(x+1) and x/(x+2), it ends up interpreting these inputs as multivariate polynomials in 3 variables, x, 1/(x+1), and 1/(x+2), and the results are total nonsense.

Sympy: prevent a subscripted symbol to be evaluated

Given a symbol s, which ultimately will be an Array, I want to define the following expression
A = Array([-s[1]/2, s[0]/2])
but I'd like A to be evaluated only when I compute some other expressions containing it, because s changes over time. I tried
A = UnevaluatedExpr(Array([-s[1]/2,s[0]/2]))
but I got the error TypeError: 'Symbol' object is not subscriptable, which make me think that some evaluation is performed on s.
Thanks for your patience, I'm just learning Sympy and I'm used to Maxima where this kind of construct is straightforward. To be more precise, with Maxima the full working code I'm trying to translate into Sympy is (in Maxima everything is a symbol, colon is the assignment operator, ev forces evaluation with custom values, the dot before diff is the vector scalar product):
A: [-s[2],s[1]]/2; /* define A in terms of subscripted symbols */
P1: [x1,y1];
P2: [x2,y2];
segment: P1+t*(P2-P1); /* --> [t*(x2-x1)+x1,t*(y2-y1)+y1] */
factor(integrate(ev(A,s=segment).diff(segment,t),t,0,1)); /* integrates the scalar product of A evaluated over segment and the derivative of segment */
Follow up
Thanks to Oscar answer I was able to come up with a working Sympy translation of the above Maxima code (improvements are welcomed!):
from sympy import *
def dotprod(*vectors): # scalar product, is there a built in better way?
return sum(Mul(*x) for x in zip(*vectors))
s = IndexedBase('s')
A = Array([-s[1]/2,s[0]/2])
t,x1,y1,x2,y2 = symbols('t x1 y1 x2 y2')
P1 = Array([x1,y1])
P2 = Array([x2,y2])
segment = P1 + t * (P2-P1)
dotprod(A.subs(s,segment),segment.diff(t)).integrate((t,0,1)).factor()
Apart from the IndexedBase magic the structure of the code in Maxima and Sympy is very similar.
I'm not sure I understand what you want. It's possible that your problem is better approached in a different way rather than using Array. In any case a direct answer to your question is that you can use IndexedBase to make a subscriptable symbol:
In [1]: s = IndexedBase('s')
In [2]: A = Array([-s[1]/2, s[0]/2])
In [3]: A
Out[3]:
⎡-s[1] s[0]⎤
⎢────── ────⎥
⎣ 2 2 ⎦

Sympy: Simplify small compound fraction with squares and roots

I have got the following situation (in Sympy 1.8):
from sympy import *
u = symbols('u') # not necessarily positive
term = sqrt(1/u**2)/sqrt(u**2)
The term renders as
How can I simplify this to 1/u**2, i.e. ?
I have tried many functions from https://docs.sympy.org/latest/tutorial/simplification.html, and some arguments listed in https://docs.sympy.org/latest/modules/simplify/simplify.html but could not get it to work.
The variable needs to be declared as real number:
u=symbols('u', real=True)
Then the term is auto-simplified.
(I suggested a corresponding Sympy documentation change.)

Evaluate constraint expression as boolean

I want to evaluate if a constraint is respected or not in Pyomo when the values of the variables contained in constraint expression are known.
Use case: We know that one particular constraint sometimes makes the problem infeasible, depending on the value of the variable. Instead of sending the problem to the solver to test if the problem is feasible, converting the constraint expression to a boolean type would be enough to determine if the constraint is the culprit.
For the sake of providing a feasible example, here would be the code:
from pyomo.environ import ConcreteModel, Var, Constraint
model = ConcreteModel()
model.X = Var()
def constraint_rule(model):
return model.X <= 1
model.a_constraint = Constraint(rule=constraint_rule)
Now, let's try to work with the expression to evaluate:
# Let's define the expression in this way:
expression = constraint_rule(model)
# Let's show that the expression is what we expected:
print(str(expression))
The previous statement should print X <= 1.0.
Now, the tricky part is how to evaluate the expression.
if expression == True:
print("feasible")
else:
print("infeasible")
creates an TypeError Exception (TypeError: Cannot create an EqualityExpression where one of the sub-expressions is a relational expression: X <= 1.0).
The last example doesn't work because constraint_rule doesn't return a boolean but a Pyomo expression.
Finally, I know that something like
def evaluate_constraint_a_expression(model):
return value(model.X) <= 1
would work, but I can't assume that I will always know the content of my constraint expression, so I need a robust way of evaluating it.
Is there a clever way of achieving this? Like, evaluating the expression as a boolean and evaluating the left hand side and right hand side of the expression at the same time?
The solution is to use value function. Even if it says that it evaluates an expression to a numeric value, it also converts the expression to a boolean value if it is an equality/inequality expression, like the rule of a constraint.
Let's suppose that the model is defined the way it is in the question, then the rest of the code should be:
from pyomo.environ import value
if value(expression) == True:
print("feasible")
else:
print("infeasible")
where expression is defined as written in the question.
However, be advised that numeric precision in Python using this method can be different than the one provided by the solver. Therefore, it is possible that this method will show that a constraint is infeasible while it is just a matter of numeric imprecision of under 1e-10. So, while it is useful in finding if most constraints are feasible, it also generates some false positives.

how to check if sympy expression contains instance of Integral or NonElementaryIntegral?

How to check if an expression returned from sympy integrate command still contain an instance of integrals.Integral or ? NonElementaryIntegral
I am trying to check the antiderivative from sympy to see if it was successful or not, by checking if it remains unevaluated or not
For example:
from sympy import *
x=symbols('x')
isinstance(Integral(x**2, x),integrals.Integral)
Works and returns True. But if the expression has one instance Integral inside other expressions, how to check?
I need a way to look at the expression tree and see if at least one instance of integrals.Integral exist in it, and return True. I am not sure how to iterate over it and do this at this time.
I tried the following (I am very much a newbie in Python and sympy).
from sympy import *
x=symbols('x')
expr=integrate((-x**2+2)*exp(x/(x**2+2))/(x**3+2*x),x)
which gives
-Integral(-2*exp(x/(x**2 + 2))/(x**3 + 2*x), x) -
Integral(x**2*exp(x/(x**2 + 2))/(x**3 + 2*x), x)
expr.args #which is tuple
(-Integral(-2*exp(x/(x**2 + 2))/(x**3 + 2*x), x), -
Integral(x**2*exp(x/(x**2 + 2))/(x**3 + 2*x), x))
any(isinstance(m, integrals.Integral) for m in expr.args)
But this gave False, why?
I also tried
for m in expr.args:
isinstance(m, integrals.Integral)
And this gaves
False
False
I was expecting both to be True.
How to check if an expression contains at least one instance of integrals.Integral any where in it?
Update
Ok, found something. The integrals above are actually NonElementaryIntegral
and not Integral. Looking at the expression tree of expr
srepr(expr)
"Add(Mul(Integer(-1), NonElementaryIntegral(Mul(Integer(-1), Integer(2),
Pow(Add(Pow(Symbol('x'), Integer(3)), Mul(Integer(2), Symbol('x'))),
Integer(-1)), exp(Mul(Symbol('x'), Pow(Add(Pow(Symbol('x'), Integer(2)),
Integer(2)), Integer(-1))))), Tuple(Symbol('x')))), Mul(Integer(-1),
NonElementaryIntegral(Mul(Pow(Symbol('x'), Integer(2)),
Pow(Add(Pow(Symbol('x'), Integer(3)), Mul(Integer(2), Symbol('x'))),
Integer(-1)), exp(Mul(Symbol('x'), Pow(Add(Pow(Symbol('x'), Integer(2)),
Integer(2)), Integer(-1))))), Tuple(Symbol('x')))))"
So I need to look for both Integral and NonElementaryIntegral. But so far, I do not know how to check for NonElementaryIntegral since I do not know in which class it is supposed to be. It is not integral.NonElementaryIntegral and need to find where this lives.
any(isinstance(mx, integrals.NonElementaryIntegral) for mx in anti.args)
gives
error: module 'sympy.integrals.integrals' has no attribute
'NonElementaryIntegral'
The page http://docs.sympy.org/latest/modules/integrals/integrals.html only says
If the indefinite Integral returned by this function is an instance of
NonElementaryIntegral, that means that the Risch algorithm has proven that
integral to be non-elementary.
Ok, but how to check for it?
expr.has(Integral)
does this. The class NonElementaryIntegral inherits from Integral, so according to inheritance rules it suffices to check for Integral.
A self-contained example would be
from sympy import *
x = symbols('x')
expr = integrate(exp(x**4)/(x**2+1), x)
print(expr.has(Integral))
You can find detailed information about the class names by using
print([type(a) for a in preorder_traversal(expr)])