1

I'm trying to solve the following equation, with python 3.6.3:

enter image description here

I did

from sympy import *
x = Symbol('x', real=True)
solve(abs((abs(x**2-1)-x))-x)

but I get the following message:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python36-32\lib\site-packages\sympy\solvers\solvers.py", line 1065, i
n solve
solution = _solve(f[0], *symbols, **flags)
  File "C:\Python36-32\lib\site-packages\sympy\solvers\solvers.py", line 1366, i
n _solve
candidates = _solve(piecewise_fold(expr), symbol, **flags)
  File "C:\Python36-32\lib\site-packages\sympy\solvers\solvers.py", line 1634, i
n _solve
raise NotImplementedError('\n'.join([msg, not_impl_msg % f]))
NotImplementedError: multiple generators [x, Abs(-x**2 + x + 1)]
No algorithms are implemented to solve equation -x + Abs(-x**2 + x + 1)

But with python 2.7.14 and matlab I get answers. Am I missing something?

Luo Kaisa
  • 147
  • 5

1 Answers1

1

This gives [1, -1 + sqrt(2), 1 + sqrt(2)] if you use the current master and manually rewrite the expression as Piecewise. Apparently the rewriting is incomplete when done by solve itself:

>>> solve((abs((abs(x**2-1)-x))-x).rewrite(Piecewise))
[1, -1 + sqrt(2), 1 + sqrt(2)]

The SymPy codebase could be changed with the following diff to correct the problem:

diff --git a/sympy/solvers/solvers.py b/sympy/solvers/solvers.py
index 172d504..96bfa94 100644
--- a/sympy/solvers/solvers.py
+++ b/sympy/solvers/solvers.py
@@ -1020,8 +1020,13 @@ def _sympified_list(w):
         # Abs
         fi = fi.replace(Abs, lambda arg:
             separatevars(Abs(arg)) if arg.has(*symbols) else Abs(arg))
-        fi = fi.replace(Abs, lambda arg:
-            Abs(arg).rewrite(Piecewise) if arg.has(*symbols) else Abs(arg))
+        while True:
+            was = fi
+            fi = fi.replace(Abs, lambda arg:
+                (Abs(arg).rewrite(Piecewise) if arg.has(*symbols)
+                else Abs(arg)))
+            if was == fi:
+                break

         for e in fi.find(Abs):
             if e.has(*symbols):
smichr
  • 16,948
  • 2
  • 27
  • 34
  • I've updated SymPy to the latest version, 1.4, but I get almost the samer error. The only differences are the line numbers in C:\Python36-32\lib\site-packages\sympy\solvers\solvers.py – Luo Kaisa Sep 22 '19 at 18:54
  • I tried with latest master and got `NotImplementedError: solving Abs(-x + Piecewise((x**2 - 1, x**2 - 1 >= 0), (1 - x**2, True))) when the argument is not real or imaginary. ` – Oscar Benjamin Sep 22 '19 at 21:25
  • Indeed...the updated version I was using was the one available through repl.it. Answer updated. – smichr Sep 23 '19 at 15:47
  • @smichr, it works now, but with python 2.7.14, it works without any rewrite! Is it a bug on python 3? – Luo Kaisa Sep 23 '19 at 20:31
  • I tested it with 2.7.7 and it worked. Not sure why it would work without rewrite in a later version. I updated the answer with a diff that could be used to fix SymPy. Perhaps you would like to report this issue at https://github.com/sympy/sympy/issues. – smichr Sep 24 '19 at 14:31