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

sympy.solve returns imaginary solutions contrary to given assumptions #9973

Open
woodscn opened this issue Oct 7, 2015 · 6 comments
Open

Comments

@woodscn
Copy link
Contributor

woodscn commented Oct 7, 2015

>>> import sympy
>>> x = sympy.Symbol('x', real=True)
>>> y = sympy.Symbol('y', real=True)
>>> z = sympy.Symbol('z', real=True)
>>> eq = sympy.Eq(x**2 + y**2 + z**2 - 1, 0)
>>> sympy.solve(eq.subs({y: 1}), x)
[-I*z, I*z]

Given the assumptions for x, this result is clearly wrong. For this problem, I would expect something more like this:

x == z == 0
@woodscn
Copy link
Contributor Author

woodscn commented Oct 9, 2015

I should mention I'm interested in doing work on this, if someone can point me in the right direction.

@asmeurer
Copy link
Member

asmeurer commented Oct 9, 2015

What does it return if no assumptions are set?

@woodscn
Copy link
Contributor Author

woodscn commented Oct 9, 2015

Same result, though I don't really think that should be a problem, since x could certainly be imaginary in that case.

@smichr
Copy link
Member

smichr commented Oct 10, 2015

The solver tries to determine solutions for x that don't violate assumptions. The two results are correct in that regard. The solver doesn't try to figure out what values of z will make the the solution match the assumptions on x, however, and I'm not sure that one should change "check_assumptions" to do so since solving for values satisfying the assumptions is beyond to scope of checking that the assumptions are not violated. But perhaps when there are assumptions on x (as in your case) another function which tries to reduce a set of expressions to the values that would make them true might be in order, e.g. given expressions (e1..en) univariate in x what values of x make them all real...or positive...or something else. For example, for a single expression:

>>> var('x', real=True)
x
>>> e=I*x
>>> Union(solve(e>0).as_set(),solve(e<0).as_set(),Eq(e,0).as_set()) # e is real
{0}
>>> Union(solve(e>0).as_set()) # e is positive
EmptySet()
>>> Union(solve(e>0).as_set(),Eq(e,0).as_set()) # e is nonnegative
{0}

@woodscn
Copy link
Contributor Author

woodscn commented Oct 10, 2015

I don't think I agree that this is out of scope. I am asking solve to take an expression, and to rearrange it based on the assumptions inherent in the variables. There's no difference in the expression I'm handing sympy between variables X, Y, and Z, so why should solve ignore the assumptions on one of them but not the other?

To put another way, solve was given a well-posed problem with a unique, specific, solution, but it stopped halfway through solving it. Instead, solve should do everything possible to return the simplest possible answer. In this case, that is simple, since the product of an imaginary number and a non-zero real number will always be imaginary, and solve knows that is not a solution to the problem it was given.

Individuals can certainly enforce this themselves, using something like the example you showed. Unfortunately, this is not really a good solution if you are using sympy for code generation or anything else that needs to be automatic.

On Oct 10, 2015, at 9:37 AM, Christopher Smith notifications@github.com wrote:

The solver tries to determine solutions for x that don't violate assumptions. The two results are correct in that regard. The solver doesn't try to figure out what values of z will make the the solution match the assumptions on x, however, and I'm not sure that one should change "check_assumptions" to do so since solving for values satisfying the assumptions is beyond to scope of checking that the assumptions are not violated. But perhaps when there are assumptions on x (as in your case) another function which tries to reduce a set of expressions to the values that would make them true might be in order, e.g. given expressions (e1..en) univariate in x what values of x make them all real...or positive...or something else. For example, for a single expression:

var('x', real=True)
x
e=I*x
Union(solve(e>0).as_set(),solve(e<0).as_set(),Eq(e,0).as_set()) # e is real
{0}
Union(solve(e>0).as_set()) # e is positive
EmptySet()
Union(solve(e>0).as_set(),Eq(e,0).as_set()) # e is nonnegative
{0}

Reply to this email directly or view it on GitHub.

@smichr
Copy link
Member

smichr commented Oct 11, 2015

I agree. I am just saying that it should probably be a function of its own, not an add-on to check_assumptions.

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

4 participants