# is_real vs. in RR for variables

It seems that - if x is a variable that I assume to be real - that x in RR gives not the same as x.is_real() :

var("x y")
assume(x,"real")

print(bool(x in RR))      # should give True ???
print(x.is_real())

print(abs(y) in RR)       # should give True ???
print(abs(y).is_real())

print(pi in RR)
print(pi.is_real())

print(I in RR)
print(((I + y) - y).is_real())     # I must create some expression since I.is_real() gives an error


output:

False
True
False
True
True
True
False
False


I don't understand the first and third output. I would expect TRUE for them since I was thinking that x in RR gives True if sagemath (can proove that) x is real.

Does anybody know why sagemath behaves like that ?

edit retag close merge delete

Sort by » oldest newest most voted

You can read the documentation for is_real by evaluating x.is_real?: "Return True if this expression is known to be a real number." In particular, it is defined for expressions, which in Sage can include variables. If you evaluate parent(x), the answer will be Symbolic Ring, the same as parent(pi).

RR, on the other hand, is "An approximation to the field of real numbers using floating point numbers with any specified precision." For something to lie in RR, there must be a way to convert it to an actual floating point number, so pi in RR will return True, whereas x in RR will not:

sage: RR(pi)
3.14159265358979


and

sage: RR(x)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)

[snip]

TypeError: Cannot evaluate symbolic expression to a numeric value.


and

sage: RR(I)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)

[snip]

TypeError: unable to convert '1.00000000000000*I' to a real number

more

OK, this explanation seems to be reasonable. But maybe the site https://doc.sagemath.org/html/en/tutorial/tour_rings.html should be edited (adding "An approximation to the field of real numbers using floating point numbers with any specified precision"). Currently there is: "the real numbers, called RR in Sage". Ok, x is not a number but a variable. But it should be emphasized that in RR are only specific real numbers (convertible to floating point), not variables (representing any number).

This site may also be interesting for someone like me who is new to sagemath: https://ask.sagemath.org/question/9950/what-are-the-different-real-numbers-in-sage/

To make it short, x belongs to RR if x is real AND a constant (or an expression that can be converted to a constant), or am I wrong ?

Now it's clear that

print(ZZ.is_exact())
print(QQ.is_exact())
print(RR.is_exact())
print(CC.is_exact())


gives:

True
True
False
False


Is there any ring - call it RING - that is like the real numbers used in mathematics, so that

x in RING

gives True then and only then if x.is_real() is true ? (Just for interest - I know that I can use is_real() and this should normally be good).

What may also be interesting, is: On some other site I found that sagemath cannot prove that

2*(cos(3/7*pi) - cos(2/7*pi) + cos(1/7*pi))-1


is exactly zero.

print((2*(cos(3/7*pi) - cos(2/7*pi) + cos(1/7*pi))-1).simplify_full())
print((2*(cos(3/7*pi) - cos(2/7*pi) + cos(1/7*pi))-1).n())

1 + I * (2*(cos(3/7*pi) - cos(2/7*pi) + cos(1/7*pi))-1) in RR


Output:

2*cos(3/7*pi) - 2*cos(2/7*pi) + 2*cos(1/7*pi) - 1
0.000000000000000

True


It seems that sagemath rounds the numerical approximation of the first expression exactly to zero and so it says that the imaginary part of the third expression is zero and so the expression is in RR. But I wouldn't see a problem if the answer was False - in case the approximation of the imaginary part would give some small nonzero number.

more

The "Symbolic Ring" SR is probably the closest thing to that, or rather the subring of SR consisting of those elements which are known to be real, either because they can be converted to RR or because they have been declared real using an assume statement.

( 2022-05-10 07:00:15 +0200 )edit

On some other site I found that sagemath cannot prove that

2(cos(3/7pi) - cos(2/7pi) + cos(1/7pi))-1

is exactly zero.

Well...

sage: QQbar(2*(cos(3/7*pi) - cos(2/7*pi) + cos(1/7*pi))-1).is_zero()
True


And this comparison is exact... One can even do directly :

sage: (2*(cos(3/7*pi) - cos(2/7*pi) + cos(1/7*pi))-1).is_zero()
True


HTH,

( 2022-05-10 09:24:04 +0200 )edit