Sympy solve() stops working with a single linear equation when magnitude of floats changes

StackOverflow https://stackoverflow.com/questions/22571673

  •  19-06-2023
  •  | 
  •  

Question

I've tried this in sympylive and on my own recent Anaconda iPython 'sympy version 0.7.4.1' with the same result:

m1,m2,r, F, G = symbols("m_1 m_2 r F_g G")
G = Float("6.67e-8")
rhs = (G * m1 * m2/r**2)


eq = Eq(F, rhs)
print eq

s=solve(eq, m1)
print s

which gave the result:

F_g == 6.67e-8*m_1*m_2/r**2
[14992503.7481259*F_g*r**2/m_2]

I reran the program with a single change - changing e-8 to e-9

G = Float("6.67e-9")

which gave the result

F_g == 6.67e-9*m_1*m_2/r**2
[]

This happens consistently in equations with small python floats or sympy Floats.

I've noticed another report of basic algebra bugs in version 0.72, but see that people use it for calculus. Am I doing something really stupid, or is this a bug in sympy solver. If it is a bug, how do I work around it?

Was it helpful?

Solution

This looks like a bug. I haven't read through their source code thoroughly enough to say for sure, but I'd go ahead and report it and then use a workaround for now.

There are some ways to address the problem. To start out, you could look at how SymPy is installed. I use the development version of SymPy and have gmpy installed as a backend for all the arbitrary precision arithmetic. On my system this problem shows up between 6.67E-32 and 6.67E-33 instead of 6.67E-8 and 6.67E-9. Getting the development release and switching the backend may help. On the other hand, that is just a guess about your system and how SymPy is configured. I could be entirely wrong.

Changing the set up only partially avoids the error. Here is a modified version of your code that avoids this problem entirely:

import sympy as sy
m1, m2, r, F, G = sy.symbols("m_1, m_2, r, F_g, G")
rhs = (G * m1 * m2/r**2)
eq = sy.Eq(F, rhs)
print eq
s=sy.solve(eq, m1)
print s[0].subs(G, sy.Float("6.67E-10000000000000000000", 1000))

The only difference is that this code has SymPy do all the work with symbols and then substitutes the floating point number in at the end. This returns the correct answer on my machine in spite of the outrageous exponent. The second parameter used to instantiate the Float object is the precision. This shows the answer to 1000 digits of precision (though this approach works with the default precision as well).

OTHER TIPS

Try using SymPy 0.7.5. This bug has been fixed in that version.

Try passing the flag rational=False to solve.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top