sagemath / sage

Main repository of SageMath
https://www.sagemath.org
Other
1.35k stars 462 forks source link

is_real method should exist for elements of AA, ZZ, QQ,..., and be fixed where it is already defined #16436

Open seblabbe opened 10 years ago

seblabbe commented 10 years ago

The function is_real is useful but it is not practical because it it not implemented for every types of numbers in Sage. And I do not want to do type checking before being able to use it in my code.

sage: CC(3).is_real()
True
sage: RR(3).is_real()
True
sage: SR(3).is_real()
True
sage: ZZ(3).is_real()
Traceback (most recent call last):
...
AttributeError: 'sage.rings.integer.Integer' object has no attribute 'is_real'
sage: QQ(3).is_real()
Traceback (most recent call last):
...
AttributeError: 'sage.rings.rational.Rational' object has no attribute 'is_real'
sage: AA(3).is_real()
Traceback (most recent call last)
...
AttributeError: 'AlgebraicReal' object has no attribute 'is_real'
sage: AlgebraicNumber(3).is_real()
Traceback (most recent call last)
...
AttributeError: 'AlgebraicNumber' object has no attribute 'is_real'

sage: RDF(3).is_real()
AttributeError: 'sage.rings.real_double.RealDoubleElement' object has no attribute 'is_real'

sage: QQbar(3).is_real()
AttributeError: 'AlgebraicNumber' object has no attribute 'is_real'

I am sure I forget some other rings...

We need more of this kind of consistency in Sage. is_imaginary is another example.

The .is_real() method does not handle NaN and +/-Infinity correctly, for example:

sage: CC(NaN).is_real()
True

Component: algebra

Issue created by migration from https://trac.sagemath.org/ticket/16436

edd8e884-f507-429a-b577-5d554626c0fe commented 10 years ago
comment:1

Hi Sebastien. Note that you can also use coercion with the poorest real representation:

sage: AA(3) in RealField(2)
True
sage: CC(3) in RealField(2)
True
sage: RR(3) in RealField(2)
True
sage: SR(3) in RealField(2)
True
sage: ZZ(3) in RealField(2)
True
sage: QQ(3) in RealField(2)
True
sage: AA(3) in RealField(2)
True
sage: QQbar(3) in RealField(2)
True

though you need to be careful with NaN and +/-Infinity that also belong to RealField(2). By the way:

sage: SR(Infinity).is_real()
True
seblabbe commented 10 years ago

Description changed:

--- 
+++ 
@@ -20,6 +20,10 @@
 Traceback (most recent call last)
 ...
 AttributeError: 'AlgebraicReal' object has no attribute 'is_real'
+sage: AlgebraicNumber(3).is_real()
+Traceback (most recent call last)
+...
+AttributeError: 'AlgebraicNumber' object has no attribute 'is_real'

I am sure I forget some other rings...

seblabbe commented 10 years ago
comment:3

Replying to @sagetrac-tmonteil:

Hi Sebastien. Note that you can also use coercion with the poorest real representation:

I have been using monkey tricks like that for too long now like .n().imag() == 0. I want a clean solution. It should be normal to ask if some eigenvalue of some matrix is a real number.

sage: M = identity_matrix(RR,4)
sage: [a.is_real() for a in M.eigenvalues()]
[True, True, True, True]
sage: M = identity_matrix(ZZ,4)
sage: [a.is_real() for a in M.eigenvalues()]
Traceback (most recent call last):
...
AttributeError: 'sage.rings.rational.Rational' object has no attribute 'is_real'
sage: M = random_matrix(ZZ,4)
sage: [a.is_real() for a in M.eigenvalues()]
Traceback (most recent call last):
...
AttributeError: 'AlgebraicNumber' object has no attribute 'is_real'
seblabbe commented 10 years ago

Description changed:

--- 
+++ 
@@ -1,5 +1,5 @@

-The function ``is_real`` is useful but it is not practical because it it not implemented for every types of numbers in Sage. And I do not want to do type checking before being able to use it in my code.
+The function `is_real` is useful but it is not practical because it it not implemented for every types of numbers in Sage. And I do not want to do type checking before being able to use it in my code.

sage: CC(3).is_real() @@ -28,5 +28,5 @@

I am sure I forget some other rings...

-We need more of this kind of consistency in Sage. is_imaginary is another example. +We need more of this kind of consistency in Sage. is_imaginary is another example.

edd8e884-f507-429a-b577-5d554626c0fe commented 10 years ago
comment:5

If, as i proposed on sage-devel we could have an overlay (say, RR) for real fields, the syntax CC(3) in RR would be very readable. The only problem with CC(3) in RealField(2) is about NaN and +/-Infinity, but you should notice that the same problem exists with the current .is_real() methods, so the solution is not clean either.

edd8e884-f507-429a-b577-5d554626c0fe commented 10 years ago

Description changed:

--- 
+++ 
@@ -1,4 +1,3 @@
-
 The function `is_real` is useful but it is not practical because it it not implemented for every types of numbers in Sage. And I do not want to do type checking before being able to use it in my code.

@@ -24,9 +23,23 @@ Traceback (most recent call last) ... AttributeError: 'AlgebraicNumber' object has no attribute 'is_real' + +sage: RDF(3).is_real() +AttributeError: 'sage.rings.real_double.RealDoubleElement' object has no attribute 'is_real' + +sage: QQbar(3).is_real() +AttributeError: 'AlgebraicNumber' object has no attribute 'is_real' +


 I am sure I forget some other rings...

 We need more of this kind of consistency in Sage. `is_imaginary` is another example.

+The `.is_real()` method does not handle `NaN` and `+/-Infinity` correctly, for example:
+
+```
+sage: CC(NaN).is_real()
+True
+```
+
rwst commented 9 years ago
comment:8

Replying to @sagetrac-tmonteil:

Hi Sebastien. Note that you can also use coercion with the poorest real representation:

sage: AA(3) in RealField(2)
True

See #12967 and #17984 for why x in RR will determine elementship in RR not in the mathematical R. For this is_real is meant.

kedlaya commented 8 years ago
comment:9

One clean way to implement is_real might be to compare x with its conjugate, which is implemented quite often:

sage: def is_real(x):
....:     return(x == x.conjugate())
....:
sage: is_real(ZZ(3))
True
sage: is_real(QQ(3))
True
sage: is_real(AA(3))
True
sage: is_real(RR(3))
True
sage: is_real(CC(3))
True

One could handle is_imaginary similarly.