Sympy polynomial change domain to integers with base m - sympy

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)

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.

How to obtain only rational and not floating point results using sympy

I consider following matrices:
M1 = Matrix([[1/7,2/7],[3/7,4/7]])
M2 = Matrix([[1,2],[3,4]])/7
which are evidently identical, but when I determine their determinant I obtain different results:
print(M1.det())
print(M2.det())
giving the following results:
-0.0408163265306122
-2/49
I would like the first result to be expressed as a rational and not as a floating point.
This is an example of one of the gochas and pitfalls from SymPy's documentation. My answer will basically reiterate what is said there. I highly recommend going through it.
When you type 1/7, the Python interpreter changes it into a float before SymPy has a chance to identify it as a rational number. In order for SymPy to evaluate it before Python does, you need to use some other method. You have already shown one of those other methods with M2: divide a SymPy object by 7 instead of a Python int by 7. Here are a few other ways:
from sympy import *
M = Matrix([[Rational(1, 7),Rational(2, 7)],[Rational(3, 7),Rational(4, 7)]]) # create a Rational object
print(det(M))
M = Matrix([[S(1)/7,S(2)/7],[S(3)/7,S(4)/7]]) # divide a SymPy Integer by 7
print(det(M))
M = Matrix([[S("1/7"),S("2/7")],[S("3/7"),S("4/7")]]) # let SymPy interpret it
print(det(M))
M = Matrix([[1,2],[3,4]])/7 # divide a SymPy Matrix by 7
print(det(M))
M = S("Matrix([[1/7,2/7],[3/7,4/7]])") # throw the whole thing into SymPy
print(det(M))
All of the above will give rational determinants. There are probably many more ways to make SymPy identify a rational number.

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 do I display a full expression in sympy?

I am trying to use sympy in a Jupyter notebook to document and perform a series of mathematical cacluations in a reporducible way.
If I define the following:
from sympy import *
init_printing()
x, y, z = symbols("x y z")
x=y+z
x
then I can display the value of x (that is, y+z).
How do I display the full equation (x=y+z)?
Running Eq(x,y+z), even with evaluate=False) returns the expression with the value of x substituted (y+z=y+z).
I tried using Eq(S('x'),y+z), also Eq(S('x'),x) and sympy keep returning a boolean variable.
So I found a way to display it using the Ipython built-in functions:
from sympy import *
from IPython.display import display, Math
init_printing()
x, y, z = symbols("x y z")
x=y+z
display(Math('x = '+latex(x)))
I think that this is a more general solution to the problem.
Although you first declare x as a sympy.Symbol, once you perform the assignment x=y+z, x becomes an alias for y+z. Whenever you use x from that point after, x will be automatically translated by python as y+z.
If you insist on this workflow, you could use Eq(S('x'),y+z) to display the equation.
I know this isn't exactly the answer, but for those just looking for a neat print of the right-hand-side of a function f(x,y,z,...), you can just do f.subs(x,x) like so:
import sympy as sp
x,y,z=sp.symbols('x,y,z')
f=x+2*y+3*sp.exp(z)
f.subs(x,x)

Inequality validation checking based on assumption in 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