Search code examples
pythonmathformulasympy

Formula solver that solves for x in 15*8-2**x=x doesn't finish computing


So I don't know what the root issue is (I don't know if it happens with any other formula), but whenever I type in 15*8-2^x=x and solve for x with my formula solver using r = solve(leftside - rightside, user_choice) the program just never finishes running. I have a pprint(r) line in the function, but the program just never gets to that point. (-2**x=x solve for x works fine tho)

After I terminate the program I get like twenty error messages, example:

File "/Users/myusername/.conda/envs/formula calculator/lib/python3.8/site-packages/sympy/solvers/solvers.py", line 1095, in solve
    solution = _solve(f[0], *symbols, **flags)

I tried 15*8-2**x=x in Symbolab and it solved it fine: https://www.symbolab.com/solver/step-by-step/solve%20for%20x%2C%2015%5Ccdot8-2%5E%7Bx%7D%3Dx

*I'm not a mathematician and these calculations are way above my understanding, I just thought it was weird that it never finished or showed an error when Symbolab managed to solve it. So what could be causing this behaviour?

edit: stack trace:

Traceback (most recent call last):
  File "/Users/torrinleonard/PycharmProjects/formula calculator/Complete_solver.py", line 38, in <module>
    Rearrange_input()
  File "/Users/torrinleonard/PycharmProjects/formula calculator/Complete_solver.py", line 29, in Rearrange_input
    r = solve(l - r, user_choice)
  File "/Users/torrinleonard/.conda/envs/formula calculator/lib/python3.8/site-packages/sympy/solvers/solvers.py", line 1095, in solve
    solution = _solve(f[0], *symbols, **flags)
  File "/Users/torrinleonard/.conda/envs/formula calculator/lib/python3.8/site-packages/sympy/solvers/solvers.py", line 1717, in _solve
    result = list(map(simplify, result))
  File "/Users/torrinleonard/.conda/envs/formula calculator/lib/python3.8/site-packages/sympy/simplify/simplify.py", line 606, in simplify
    expr = expr.replace(
  File "/Users/torrinleonard/.conda/envs/formula calculator/lib/python3.8/site-packages/sympy/core/basic.py", line 1497, in replace
    rv = walk(self, rec_replace)
  File "/Users/torrinleonard/.conda/envs/formula calculator/lib/python3.8/site-packages/sympy/core/basic.py", line 1471, in walk
    newargs = tuple([walk(a, F) for a in args])
  File "/Users/torrinleonard/.conda/envs/formula calculator/lib/python3.8/site-packages/sympy/core/basic.py", line 1471, in <listcomp>
    newargs = tuple([walk(a, F) for a in args])
  File "/Users/torrinleonard/.conda/envs/formula calculator/lib/python3.8/site-packages/sympy/core/basic.py", line 1471, in walk
    newargs = tuple([walk(a, F) for a in args])
  File "/Users/torrinleonard/.conda/envs/formula calculator/lib/python3.8/site-packages/sympy/core/basic.py", line 1471, in <listcomp>
    newargs = tuple([walk(a, F) for a in args])
  File "/Users/torrinleonard/.conda/envs/formula calculator/lib/python3.8/site-packages/sympy/core/basic.py", line 1481, in walk
    rv = F(rv)
  File "/Users/torrinleonard/.conda/envs/formula calculator/lib/python3.8/site-packages/sympy/core/basic.py", line 1490, in rec_replace
    v = _value(expr, result)
  File "/Users/torrinleonard/.conda/envs/formula calculator/lib/python3.8/site-packages/sympy/core/basic.py", line 1455, in <lambda>
    _value = lambda expr, result: value(expr)
  File "/Users/torrinleonard/.conda/envs/formula calculator/lib/python3.8/site-packages/sympy/simplify/simplify.py", line 614, in <lambda>
    lambda x: x.func(*[simplify(i, **kwargs) for i in x.args]),
  File "/Users/torrinleonard/.conda/envs/formula calculator/lib/python3.8/site-packages/sympy/simplify/simplify.py", line 614, in <listcomp>
    lambda x: x.func(*[simplify(i, **kwargs) for i in x.args]),
  File "/Users/torrinleonard/.conda/envs/formula calculator/lib/python3.8/site-packages/sympy/simplify/simplify.py", line 699, in simplify
    expr = shorter(expand_log(expr, deep=True), logcombine(expr))
  File "/Users/torrinleonard/.conda/envs/formula calculator/lib/python3.8/site-packages/sympy/simplify/simplify.py", line 1119, in logcombine
    return bottom_up(expr, f)
  File "/Users/torrinleonard/.conda/envs/formula calculator/lib/python3.8/site-packages/sympy/simplify/simplify.py", line 1198, in bottom_up
    rv = F(rv)
  File "/Users/torrinleonard/.conda/envs/formula calculator/lib/python3.8/site-packages/sympy/simplify/simplify.py", line 1097, in f
    log1[Mul(*k)] = log(logcombine(Mul(*[
  File "/Users/torrinleonard/.conda/envs/formula calculator/lib/python3.8/site-packages/sympy/simplify/simplify.py", line 1098, in <listcomp>
    l.args[0]**Mul(*c) for c, l in log1.pop(k)]),
  File "/Users/torrinleonard/.conda/envs/formula calculator/lib/python3.8/site-packages/sympy/core/expr.py", line 239, in __pow__
    return self._pow(other)
  File "/Users/torrinleonard/.conda/envs/formula calculator/lib/python3.8/site-packages/sympy/core/decorators.py", line 266, in _func
    return func(self, other)
  File "/Users/torrinleonard/.conda/envs/formula calculator/lib/python3.8/site-packages/sympy/core/decorators.py", line 136, in binary_op_wrapper
    return func(self, other)
  File "/Users/torrinleonard/.conda/envs/formula calculator/lib/python3.8/site-packages/sympy/core/expr.py", line 235, in _pow
    return Pow(self, other)
  File "/Users/torrinleonard/.conda/envs/formula calculator/lib/python3.8/site-packages/sympy/core/cache.py", line 72, in wrapper
    retval = cfunc(*args, **kwargs)
  File "/Users/torrinleonard/.conda/envs/formula calculator/lib/python3.8/site-packages/sympy/core/power.py", line 336, in __new__
    obj = b._eval_power(e)
  File "/Users/torrinleonard/.conda/envs/formula calculator/lib/python3.8/site-packages/sympy/core/numbers.py", line 2347, in _eval_power
    result = Integer(x**abs(expt.p))
KeyboardInterrupt

Solution

  • It looks like the magnitude of the constant is causing troubles since smaller values are solved easily:

    >>> from sympy.abc import x
    >>> from sympy import *
    >>> solve(1-2**x-x)
    [0]
    >>> solve(2-2**x-x)
    [(-LambertW(log(16)) + log(4))/log(2)]
    >>> solve(5-2**x-x)
    [(-LambertW(log(4294967296)) + log(32))/log(2)]
    

    In this case, however, the exact value doesn't help in finding the solution so we can replace the 120 with Symbol('120'):

    >>> solve(Symbol('120')-2**x-x,x)
    120 - LambertW(exp(120*log(2))*log(2))/log(2)
    

    As @oscar-benjamin points out, setting simpliy=False will give an answer in the same amount of time but you will also get a large integer in the result:

    [-LambertW(1329227995784915872903807060280344576*log(2))/log(2) + 120]
    

    If you only want a numerical value you can do that directly with nsolve and a reasonable guess for the solution:

    >>> nsolve(120-2**x-x, 7)
    6.82244407754025