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

Regression in solveset for quadratic with symbolic coefficients #22058

Closed
oscarbenjamin opened this issue Sep 9, 2021 · 3 comments
Closed

Regression in solveset for quadratic with symbolic coefficients #22058

oscarbenjamin opened this issue Sep 9, 2021 · 3 comments

Comments

@oscarbenjamin
Copy link
Contributor

oscarbenjamin commented Sep 9, 2021

This is a regression since sympy 1.8. On 1.8 we have:

In [1]: x, t = symbols('x, t')

In [2]: solveset(-sqrt(t)*x**2 + 2*x + sqrt(t), x, Reals)
Out[2]: 
    ⎧    _______         _______     ⎫
    ⎪  ╲╱ t + 1    1   ╲╱ t + 1    1 ∩ ⎨- ───────── + ──, ───────── + ──⎬
    ⎪      √tttt⎪
    ⎩                                ⎭

However on master that's:

In [11]: x, t = symbols('x, t')

In [12]: solveset(-sqrt(t)*x**2 + 2*x + sqrt(t), x, Reals)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-2-689112688710> in <module>
----> 1 solveset(-sqrt(t)*x**2 + 2*x + sqrt(t), x, Reals)

~/current/sympy/sympy/sympy/solvers/solveset.py in solveset(f, symbol, domain)
   2215     if symbol not in _rc:
   2216         x = _rc[0] if domain.is_subset(S.Reals) else _rc[1]
-> 2217         rv = solveset(f.xreplace({symbol: x}), x, domain)
   2218         # try to use the original symbol if possible
   2219         try:

~/current/sympy/sympy/sympy/solvers/solveset.py in solveset(f, symbol, domain)
   2239     f = piecewise_fold(f)
   2240 
-> 2241     return _solveset(f, symbol, domain, _check=True)
   2242 
   2243 

~/current/sympy/sympy/sympy/solvers/solveset.py in _solveset(f, symbol, domain, _check)
   1068                     u = unrad(f)
   1069                     if u:
-> 1070                         result += _solve_radical(equation, u,
   1071                                                  symbol,
   1072                                                  solver)

~/current/sympy/sympy/sympy/solvers/solveset.py in _solve_radical(f, unradf, symbol, solveset_solver)
    868         f_set = []  # solutions for FiniteSet
    869         c_set = []  # solutions for ConditionSet
--> 870         for s in result:
    871             if checksol(f, symbol, s):
    872                 f_set.append(s)

~/current/sympy/sympy/sympy/sets/sets.py in __iter__(self)
   1424             if not candidates:
   1425                 raise TypeError("None of the constituent sets are iterable")
-> 1426             raise TypeError(
   1427                 "The computation had not completed because of the "
   1428                 "undecidable set membership is found in every candidates.")

TypeError: The computation had not completed because of the undecidable set membership is found in every candidates.

There is a bug in solveset attempting to iterate over an Intersection(FiniteSet(sol1, sol2), Reals).

Bisected to 651595d from #21276.

CC @smichr

@oscarbenjamin
Copy link
Contributor Author

The problem is these lines:

if isinstance(result, (Complement, ConditionSet)):
solution_set = result
else:
f_set = [] # solutions for FiniteSet
c_set = [] # solutions for ConditionSet
for s in result:
if checksol(f, symbol, s):
f_set.append(s)
else:
c_set.append(s)
solution_set = FiniteSet(*f_set) + ConditionSet(symbol, Eq(f, 0), FiniteSet(*c_set))

Here it is assumed that if the result is not Complement or ConditionSet then it must be iterable.

Maybe Set.is_iterable should be improved so that the check could instead be something like

if result.is_iterable and result.is_finite_set:

@smichr
Copy link
Member

smichr commented Sep 9, 2021

Where did you find that test?

smichr added a commit that referenced this issue Sep 9, 2021
@oscarbenjamin
Copy link
Contributor Author

The example is a simplified version of the problem in #20370

skirpichev added a commit to skirpichev/diofant that referenced this issue Sep 10, 2021
@smichr smichr closed this as completed in bf9b489 Sep 10, 2021
oscarbenjamin added a commit to oscarbenjamin/sympy that referenced this issue Sep 11, 2021
Since Poly can handle symbolic coefficients, it is not necessary
to remove powers in them with unrad: passing the variable of
interest will allow a lower order polynomial to be solved.
e.g. unrad(sqrt(t)*x, x) is unchanged while unrad(sqrt(t)*x) is t*x**2

Also, only explicitly check solutions of FiniteSet.

Cherry-picked from bf9b489
oscarbenjamin pushed a commit to oscarbenjamin/sympy that referenced this issue Sep 11, 2021
Since Poly can handle symbolic coefficients, it is not necessary
to remove powers in them with unrad: passing the variable of
interest will allow a lower order polynomial to be solved.
e.g. unrad(sqrt(t)*x, x) is unchanged while unrad(sqrt(t)*x) is t*x**2

Also, only explicitly check solutions of FiniteSet.

Cherry-picked from bf9b489
oscarbenjamin added a commit that referenced this issue Sep 12, 2021
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