Inequality validation checking based on assumption in sympy - sympy

I want to check whether inequality a<f hold based on the following assumptions
a<b
b=d
d=e
e<f
What is the best way to verify whether inequality a<f hold based on those assumption.
I can substitute equalizes and Simplify a<b as follows
>>> from sympy import *
>>> a=Symbol('a')
>>> b=Symbol('b')
>>> c=Symbol('c')
>>> d=Symbol('d')
>>> f=a<b
>>> f.subs({b:c,c:d}).simplify()
a < d
Looking forward for suggestion

Related

Using sympy.integrate on a function that involves int()

I'm trying to integrate functions in Python. scipy.integrate.quad seems to work ok; but just be sure I'd like to check the results against other integration code. It was suggested that I try sympy.integrate. Now the code for the functions I want to integrate contains int(), which I use to convert floats into ints. This is ok for quad, but not for sympy.integrate.
Here's a simple example that reproduces the error:
import sympy
def f(x):
return sympy.exp(int(x))
sympy.symbols('x')
print(sympy.integrate(f(x),(x,0,2)))
This yields the error: TypeError: can't convert symbols to int
So is there a way to integrate functions that involve int() with scipy.integrate?
Thanks
To use integrate f must be a SymPy symbolic function which disallows your particular use of int. int(x) where x is a Symbol will always yield a type error however you could represent this symbolically using the floor function:
def f(x):
return sympy.exp(sympy.floor(x))
However, using floor may defeat some of the purpose of using SymPy in the first place because it will probably prevent discovery of an analytic solution as the following python session demonstrates:
>>> from sympy import *
>>> x = symbols("x")
>>> integrate(exp(floor(x)), (x, 0, 2)) # use of floor prevents evaluated result
Integral(exp(floor(x)), (x, 0, 2))
Though you can use the evalf method to compute a numeric result (which is ultimately performed by mpmath):
>>> integrate(exp(floor(x)), (x, 0, 2)).evalf()
3.7
(perhaps this result suggests sympy could better handle this integral? Wolfram Alpha computes this as 1 + e = 3.71828... so I suppose there is at least a floating point precision bug here too - see comment re ceiling)
In any case, I don't know if you consider that an appropriate result considering the version of f without floor:
>>> integrate(exp(x), (x, 0, 2))
-1 + exp(2)
>>> _.evalf()
6.38905609893065

How to check whether a symbolic expression is rational?

I'm using Sympy and I haven't found a simple way of testing for x ∈ Q.
Context: I have a set of solutions of a set of very simple, 2DoF eigenvalue problems (e.g.,
) and I want to check if one of these solutions is rational (or, in other words, if the solution doesn't contains a square root).
A direct way of checking is what I would like the best, but I could accept also an answer that deals with finding (not finding) a square root in the solution.
The function rational = lambda x: all(i.exp.is_Integer for i in x.atoms(Pow)) is a direct translation of your criteria to return True if all powers (if present) are integers.
>>> from sympy import Pow, S, sqrt
>>> rational = lambda x: all(i.exp.is_Integer for i in x.atoms(Pow))
>>> rational(S.Half)
True
>>> rational(sqrt(3))
False
>>> rational(3/(1+sqrt(3)))
False

Sympy polynomial change domain to integers with base m

How can I specify Poly in sympy to be on certain domain.
For example, integers based on 7, e.g, $\mathbb{Z}_7$
I'm not sure if sympy has $Z_7$, but suppose you wanted $GF(2),$ the Galois field with 2 elements. Then you can:
>>> from sympy import Poly
>>> Poly(x**2 + 2*x, domain=GF(2))
Poly(x**2, x, modulus=2)

which one of the following expressions is faster to determine index of minimum element in a list?

>>> l=[1,2,3]
>>> l.index(min(l))
>>> 0
>>> from operator import itemgetter
>>> min(enumerate(l),key=itemgetter(1))[0]
>>> 0
need to use this repeatedly inside a loop of 10,000 iterations , so which is more efficient
They have the same complexity of O(n). You can check the cpu time to see which one suits you best

How to obtain all solutions for cos(x)*cosh(x) == 1 in Sympy?

Following is the best I can get.
map(lambda n: nsolve(cos(x)*cosh(x)-1,x,3.14/2+3.14*n),range(9))
[mpf('0.0039941152964418809'),
mpf('4.730040744862704'),
mpf('7.8532046240958376'),
mpf('10.995607838001671'),
mpf('14.137165491257464'),
mpf('17.278759657399481'),
mpf('20.420352245626061'),
mpf('23.561944902040455'),
mpf('26.703537555508186')]
If you change range(9) to range(10), sympy will return an error.
ValueError: Could not find root within given tolerance. (1.59798e-17 > 2.1684e-1
9)
Try another starting point or tweak arguments.
I have asked this in the Mathematica site, Mathematica seems can provide the solutions quite accurate and fast. Check this out: how-to-obtain-all-solutions-for-cosx-coshx-1
This is a nice example of using an intelligent initial guess. If you just provide a tolerance you can find the additional solution:
>>> len([nsolve(cos(x)*cosh(x)-1,x,3.14/2+3.14*n,tol=1e-12) for n in range(10)])
10
Note, however, that the function is very steep in the region of the roots and it is unlikely that you will every end up with an x value that will make the function value small. If you know that your initial guesses leads to a root and not a discontinuity, you can safely use the verify=False to skip the verification of the solution (and verify it yourself, perhaps by taking the slope into account). I always feel safer using the bisect method, however, in these cases:
>>> f
cos(x)*cosh(x) - 1
>>> bounds = lambda i: (3.14*i, 3.14*(i+1))
>>> root = lambda i: nsolve(f, bounds(i), solver='bisect', verify=False)
>>> root(0)
mpf('0.0')
>>> root(99)
mpf('312.58846903218443')
>>> root(100)
mpf('315.73006168577422')
You can see that the function at this point is very large, but if we normalize by the derivative of the function the answer looks better:
>>> ans = _
>>> f.subs(x, ans).n(2)
2.3e+122
>>> (f/f.diff(x)).subs(x, ans).n(2)
-3.4e-15
Note: currently, it will not work to pass a normalized function to nsolve so it can be used in the solving process: nsolve only works with the numerator of the function you pass.