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

sqrt.is_negative #14815

Closed
asmeurer opened this issue Jun 21, 2018 · 7 comments · Fixed by #18597
Closed

sqrt.is_negative #14815

asmeurer opened this issue Jun 21, 2018 · 7 comments · Fixed by #18597

Comments

@asmeurer
Copy link
Member

sqrt(x).is_negative currently gives None. But if sqrt represents the principal square root, shouldn't it be False?

This came up from this StackOverflow question

@sidhantnagpal
Copy link
Member

I think it is appropriate (None) for default assumptions on x (can be complex).
Otherwise we can have sqrt(var('a', positive=True)).is_negative which gives False.

@avishrivastava11
Copy link
Contributor

@asmeurer I would like to work on this issue.
What exactly do we need to fix here can you specify again please

@smichr
Copy link
Member

smichr commented Jun 25, 2018

I think it is appropriate (None) for default assumptions on x (can be complex).

If something has a nonzero imaginary component, SymPy gives False:

>>> (1+I).is_negative
False
>>> I.is_negative
False

So I think it's fair to say that sqrt(x) will never be negative: it will either be nonnegative or have an imaginary component.

@sidhantnagpal
Copy link
Member

If something has a nonzero imaginary component, SymPy gives False

Is it better to have this instead of None?

@smichr
Copy link
Member

smichr commented Jun 25, 2018

Not to be coy, but...it depends what your assumptions are:

>>> var('x',real=False)
x
>>> x.is_negative
False

With the following diff,

diff --git a/sympy/core/power.py b/sympy/core/power.py
index f0e69a3..1172635 100644
--- a/sympy/core/power.py
+++ b/sympy/core/power.py
@@ -451,23 +451,10 @@ def _eval_is_positive(self):
                 return log(self.base).is_imaginary

     def _eval_is_negative(self):
-        if self.base.is_negative:
-            if self.exp.is_odd:
-                return True
-            if self.exp.is_even:
-                return False
-        elif self.base.is_positive:
-            if self.exp.is_real:
-                return False
-        elif self.base.is_nonnegative:
-            if self.exp.is_nonnegative:
-                return False
-        elif self.base.is_nonpositive:
-            if self.exp.is_even:
-                return False
-        elif self.base.is_real:
-            if self.exp.is_even:
-                return False
+        # it is either nonnegative or has an
+        # imaginary component (which is not negative)
+        # since I.is_negative -> False
+        return False
>>> sqrt(var('x')).is_negative
False

@Vinayak-Shukla
Copy link

Is this issue still open, if yes what needs to be done here, can anyone specify, I'd like to take up the issue.

@oscarbenjamin
Copy link
Contributor

The problem is that in sympy we don't have a clean way to distinguish when something is an ordinary number or not. We often think that Symbol('x') represents an arbitrary complex number. However users can put anything into a sqrt e.g.:

In [2]: M = MatrixSymbol('M', 2, 2)                                                                                                            

In [3]: sqrt(M)                                                                                                                                
Out[3]: 
 1/2
M   

In [4]: sqrt(M).is_negative                                                                                                                    
Out[4]: False

I don't know what kind of object possibly could have a negative sqrt (given that sympy uses the principal root) but I think we should make explicit our assumptions when writing this kind of code so e.g.:

if self.base.is_complex or self.base.is_extended_real:
    return False

If that means that it doesn't evaluate for a plain symbol then that's unfortunate and unintuitive but...

Until sympy can clean itself up so it knows when something (including a symbol) actually is a plain number we will always have situations like this.

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

Successfully merging a pull request may close this issue.

6 participants