Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

multiple generators [exp(-x), exp(-x**2)] when trying to solve(exp(-x - x ** 2), x) #17949

Closed
ischurov opened this issue Nov 22, 2019 · 8 comments

Comments

@ischurov
Copy link

ischurov commented Nov 22, 2019

I'm trying to solve equation e^{-x-x^2}=0, which does not have roots in real numbers. In sympy1.4 I get an empty list of solutions, as expected. In current sympy1.6.dev I have an error.

Python 2.7.15 (default, Jul  7 2018, 02:08:11)
[GCC 4.2.1 Compatible Apple LLVM 9.1.0 (clang-902.0.39.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from sympy import *
>>> import sympy
>>> print(sympy.__version__)
1.6.dev
>>> x = symbols('x', real=True)
>>> solve(exp(-x - x ** 2), x)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/user/soft/sympy/sympy/solvers/solvers.py", line 1198, in solve
    solution = _solve(f[0], *symbols, **flags)
  File "/Users/user/soft/sympy/sympy/solvers/solvers.py", line 1772, in _solve
    raise NotImplementedError('\n'.join([msg, not_impl_msg % f]))
NotImplementedError: multiple generators [exp(-x), exp(-x**2)]
No algorithms are implemented to solve equation exp(-x**2 - x)

At the same time, similar equation e^{x+x^2} is solved (no roots, as expected):

>>> solve(exp(x + x**2), x)
[]
@oscarbenjamin
Copy link
Collaborator

I've bisected this to 4bd14a7 from #16666.

There was a major change to the old assumptions system to ensure that real numbers are always considered finite.

Note though that your example shows the problem without using real=True:

In [1]: x = Symbol('x')                                                                                                           

In [2]: solve(exp(-x - x ** 2), x)                                                                                                
---------------------------------------------------------------------------
NotImplementedError

@oscarbenjamin
Copy link
Collaborator

The code takes a different path here:

sympy/sympy/solvers/solvers.py

Lines 2856 to 2865 in d1cd822

pos, reps = posify(lhs - rhs)
for u, s in reps.items():
if s == sym:
break
else:
u = sym
if pos.has(u):
try:
soln = _solve(pos, u, **flags)
return list(ordered([s.subs(reps) for s in soln]))

Here lhs is -x-x**2 and rhs is zoo. I guess this comes from taking logs of both sides of the original equation. When we subtract those and posify we get different results before and after the commit I referenced. In master we have:

In [1]: x = Symbol('x')                                                                                                           

In [2]: lhs = -x-x**2; rhs = zoo                                                                                                  

In [3]: lhs - rhs                                                                                                                 
Out[3]: 
   2          
- x  - x + zoo

In [4]: posify(lhs - rhs)[0]                                                                                                      
Out[4]: zoo

Whereas in 1.4 we have

In [4]: posify(lhs - rhs)[0]                                                                                                      
Out[4]: 
   2          
- x  - x + zoo

This is because posify makes symbols "positive" and the meaning of positive changed in #16666. Previously positive included oo whereas now there are both positive and extended_positive and only the latter includes oo because positive implies real which in turn imlpies finite.

So now the effect of posifying the symbols is that they become finite which means that zoo+x can evaluate to zoo.

This isn't something I particularly thought about in #16666. I'm not sure what posify should do. For example it could make symbols extended positive instead of positive. That would solve this issue but this issue can also be solved by changing the linked code in solve instead.

@oscarbenjamin
Copy link
Collaborator

I'm adding the 1.5 milestone because this could be viewed as a regression.

The question is what to do though. Should posify make symbols positive or extended_positive?

@ischurov
Copy link
Author

Thanks for quick response! I'm not sure it's relevant, but there's a difference between 1.4 and 1.6.dev before we do posify:

# 1.4
>>> lhs = -x-x**2; rhs = zoo
>>> lhs - rhs
-x**2 - x + zoo
# 1.6.dev
>>> lhs = -x-x**2; rhs = zoo
>>> lhs - rhs
zoo

Also, solve(exp(x ** 2 + x ** 4), x) give the same error while solve(exp(x ** 2 + x), x) works as expected in 1.6.dev (as I mentioned earlier).

@oscarbenjamin
Copy link
Collaborator

This is what I get on master:

In [1]: x = Symbol('x')                                                                                                           

In [2]: lhs = -x-x**2; rhs = zoo                                                                                                  

In [3]: lhs - rhs                                                                                                                 
Out[3]: 
   2          
- x  - x + zoo

In [4]: posify(lhs-rhs)                                                                                                           
Out[4]: (zoo, {x: x})

How is x defined in your example?

@ischurov
Copy link
Author

Aha, I have symbols('x', real=True)

In [5]: import sympy

In [6]: x = sympy.symbols('x', real=True)

In [7]: lhs = -x-x**2; rhs = sympy.zoo

In [8]: lhs - rhs
Out[8]: zoo

In [9]: x = sympy.symbols('x')

In [10]: lhs = -x-x**2; rhs = sympy.zoo

In [11]: lhs - rhs
Out[11]: -x**2 - x + zoo

@oscarbenjamin
Copy link
Collaborator

I've opened #17971 which fixes this in 1.5

@oscarbenjamin
Copy link
Collaborator

Closing as merged into 1.5.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants