Ignore imaginary roots in sympy

I use sympy to solve the polynomial:

x = Symbol('x') y = solve(int(row["scaleA"])*x**3 + int(row["scaleB"])*x**2 + int(row["scaleC"])*x + int(row["scaleD"]), x) 

y is a list of possible solutions. However, I need to ignore the imaginary and use only real solutions. In addition, I would like the solution as a value not to be an expression. Now it looks like this:

 [-2/3 - 55**(1/3)*(-1/2 - sqrt(3)*I/2)/3, -2/3 - 55**(1/3)*(-1/2 + sqrt(3)*I/2)/3, -55**(1/3)/3 - 2/3] 

I need the last value of the expression (-2.22756). Are there functions in sympy to simplify this?

+6
source share
5 answers

As Krastonov said, mpmath provided a simpler method:

 y = polyroots([int(row["scaleA"]), int(row["scaleB"]), int(row["scaleC"]), int(row["scaleD"])-value]) for root in y: if "j" not in str(root): value = root 
0
source

If you set x to reality, SymPy will provide you with real solutions.

 x = Symbol('x', real=True) solve(..., x) 
+9
source

This is exactly what real_roots done and is especially applicable to your case when the odds are integers:

 x = Symbol('x') eq = int(row["scaleA"])*x**3 + int(row["scaleB"])*x**2 + int(row["scaleC"])*x + int(row["scaleD"]) y = real_roots(eq, x) # gives [CRootOf(...), ...] 

The value of CRootOf instances can be estimated to whatever accuracy you need and should not contain any imaginary part. For instance,

 >>> [in(12) for i in real_roots(3*x**3 - 2*x**2 + 7*x - 9, x)] [1.07951904858] 

Note. As I recall, the decision will send back roots that it could not confirm by fulfilling the assumptions (i.e. if they were not recognized as false for the assumption, then they are returned). Also, if you want more consistent output from the solution, @PyRick, set the dict=True flag.

+1
source

solve() does not have consistent output for different types of solutions, use solveset(Eq,x,domain=S.Reals) :

  from sympy import ImageSet, S x = Symbol('x') y = solveset(int(row["scaleA"])*x**3 + int(row["scaleB"])*x**2+int(row["scaleC"])*x + int(row["scaleD"]), x, domain=S.Reals) 

http://docs.sympy.org/latest/modules/solvers/solveset.html

0
source

I was able to simply ignore solutions containing the "I" character and use .evalf() to evaluate the expression. Code now:

  x = Symbol('x') y = solve(int(row["scaleA"])*x**3 + int(row["scaleB"])*x**2 + int(row["scaleC"])*x + int(row["scaleD"]), x) for root in y: if "I" not in str(root): print("This One:" + str(root.evalf())) 
-3
source

All Articles