Open videlec opened 6 years ago
+1
:-) pushing in a minute...
Author: Vincent Delecroix
Description changed:
---
+++
@@ -1 +1,9 @@
We create a (mostly abstract) class to model the set of real numbers.
+
+We also fix
+
+```
+sage: ZZ.completion(oo, 53)
+Real Field with 53 bits of precision
+```
+as `ZZ` is complete (for the usual absolute value)!
Branch: u/vdelecroix/24456
Description changed:
---
+++
@@ -7,3 +7,7 @@
Real Field with 53 bits of precision
as ZZ
is complete (for the usual absolute value)!
+
+follow-ups:
+- #24457: rename sage.rings.real_mpfr.RealField
+- #24458: a useful real lazy field
Branch pushed to git repo; I updated commit sha1. This was a forced push. New commits:
62d2d21 | 24456: class for the field of real numbers |
For me this looks fine (I can now create the object and use it in formal expressions) and patchbot is green. If you think this is not enough for a review then please set back to "needs review".
Thanks. I also had a question turning up while working on #24457. The code here does not support RealField(prec)
anymore---the init method only has self argument, is this intended? Since real_mpfr.RealField()
will be renamed should create_RealField(prec)
be used everywhere instead?
Replying to @rwst:
Thanks. I also had a question turning up while working on #24457. The code here does not support
RealField(prec)
anymore---the init method only has self argument, is this intended?
It is intended: the field of real number is the field of real number (see e.g. wikipedia). The code provided in the branch u/vdelecroix/24456
is new, so it never used to support anything.
Since
real_mpfr.RealField()
will be renamed shouldcreate_RealField(prec)
be used everywhere instead?
No. create_RealField
is a convenience to handle options for the completion functor. There is no reason to use it directly.
The real_field.RealField
in this branch has (almost) nothing to do with real_mpfr.RealField
.
Some comments:
ZZ
should be in a separate ticket for better granularity.CompletionFunctor
to have prec
.RealField
could be a common ABC for all classes that model R, but that is not possible because it inherits from Singleton
(IMO, is a shortcoming of that class, but that is a different issue).I don't quite understand the purpose of this new RealField
. Maybe it would be good to elaborate on that.
Why is this thing a Parent
? Given that it doesn't have Elements (in the Sage sense), it probably should be a CategoryObject
and not a Parent
.
Replying to @jdemeyer:
I don't quite understand the purpose of this new
RealField
. Maybe it would be good to elaborate on that.
OK, I sort of see where this is going. But it doesn't explain why it is a Parent
.
Dependencies: #24464, #24465
Description changed:
---
+++
@@ -1,12 +1,4 @@
We create a (mostly abstract) class to model the set of real numbers.
-
-We also fix
-
-```
-sage: ZZ.completion(oo, 53)
-Real Field with 53 bits of precision
-```
-as `ZZ` is complete (for the usual absolute value)!
follow-ups:
- #24457: rename `sage.rings.real_mpfr.RealField`
I am fine making it a CategoryObject
with category Fields().Infinite()
.
This is initialized as a facade parent, so it should not have an Element
class.
Replying to @tscrim:
This is initialized as a facade parent
Why? As I said above, I don't see why this should be a Parent
in the first place.
Also, it would be good to replace the coerce_map_from
method by a real PEP 3119 check like
sage: R = RealField() # abstract real numbers
sage: issubclass(RR, R)
True
Is that in line with what you have in mind?
Replying to @jdemeyer:
Replying to @tscrim:
This is initialized as a facade parent
Why? As I said above, I don't see why this should be a
Parent
in the first place.Also, it would be good to replace the
coerce_map_from
method by a real PEP 3119 check likesage: R = RealField() # abstract real numbers sage: issubclass(RR, R) True
Is that in line with what you have in mind?
This is the kind of purposes I want this class for. RealField()
should know about all ways of modelling concretely real numbers in Sage (but how?) and it should be possible to query it about real number questions, like the example you mentioned (but how?). The main problem I have is how to handle the distinction between exact subrings (e.g. QQ) versus approximations (e.g. RDF).
Note that in your example we might also want to make the following works
sage: import numbers
sage: isinstance(RR.element_class, numbers.Real)
Replying to @videlec:
This is the kind of purposes I want this class for.
Excellent! A big +1 from me.
Replying to @videlec:
sage: import numbers sage: isinstance(RR.element_class, numbers.Real)
This already works except for the fact that RR
doesn't have an element_class
attribute:
sage: import numbers
sage: isinstance(RR.an_element(), numbers.Real)
True
But I'd really like it to work on the parent since it's the parent which models the real numbers. Also, the coercion framework mostly works with parents, so this could be useful there too.
It would be nice if this could serve as the base field for real manifolds. For the moment we have:
sage: M = Manifold(3, 'M', field='real'); M
3-dimensional differentiable manifold M
sage: M.base_field()
Real Field with 53 bits of precision
sage: M.base_field() is RR
True
which is a bit awkward, since all subsequent calculus on M
has nothing to do with RR
. Actually RR
is used as a proxy for the field of real numbers, so it would be very nice to replace it by something closer to the actual field of real numbers, as the new RealField
proposed here (as far as I understand).
Sorry for being mute, i did not have time to write something when i put this ticket back on needs-review, but i did not want it to be merged that way. Blitzkrieg is not the way, there have been too much projects within Sage dying because of a lack of consensus, and i do not want the idea of a "genuine" real field to end like this.
Of course i am in favor of having such an abstraction and i am happy that some people support this as well, however when i promoted such an idea in various sage days, tutorials, discussions, tickets, it was clear from that experience that there was no consensus about that question, at all.
Hence, i think that a collectively approved decision on such subject should happen before code. For example, the proposed branch implies behaviors such as (random undocumented examples):
sage: R = QQ.completion(infinity, infinity) ; R
Real Field
sage: QQbar(sqrt(2)).parent()
Algebraic Field
sage: R(QQbar(sqrt(2))).parent()
Algebraic Real Field
sage: QQbar(sqrt(1)).parent()
Algebraic Field
sage: R(QQbar(sqrt(1))).parent()
Rational Field
sage: 0.1 in R
False
sage: R(RDF(0.1))
1/10
sage: R(pi)
ValueError: Can't coerce `pi` in any parent `Real Field` is a facade for
sage: R(ZZ(1)).parent()
Rational Field
Which behavior do we want for this ? Which interplay with existing representations of real numbers ? What are the implications in the whole Sage ? How do we ensure a smooth transition from the current ill-named RR
and a genuine RR
corresponding to the field of real numbers ? Since real numbers are everywhere, we should think about the consequences before being tied with wrong design and the imperative of backward compatibility.
All this to say that we need to have a plan with a boarder view, on which the community agrees.
Note that Ralf opened a ticket on that subject, and since ticket #17713 already has some debates on this subject and a similar purpose, let me suggest to continue the discussion there (so that we collect every input in a single place), and make it a task with appropriate subtickets once we reach a consensus.
The depending ticket #24171 could work with numbers.*
as well, as the objects are used only internally.
Replying to @rwst:
The depending ticket #24171 could work with
numbers.*
as well, as the objects are used only internally.
Ah no, the numbers classes are abstract, sorry.
Replying to @sagetrac-tmonteil:
For example, the proposed branch implies behaviors such as (random undocumented examples):
The current RealField
as it is in the branch is a facade. Which means that it does not have any element of its own. The sets for which it is a facade are concrete subrings/subfields of the set of real numbers. In the current branch it is only QQ
and AA
. Beyond adding more subrings/subfields, I don't see how it could be otherwise.
All the examples you mention come from the way _element_constructor_
is designed for facade sets. For each set for which it is a facade the element constructor tries a conversion to this set. The behavior might be wrong, I am just explaining the mechanic.
sage: QQbar(sqrt(2)).parent() Algebraic Field sage: R(QQbar(sqrt(2))).parent() Algebraic Real Field
This is because AA(QQbar(sqrt(2)))
is the first to succeed (QQ(QQbar(sqrt(2)))
does not).
sage: QQbar(sqrt(1)).parent() Algebraic Field sage: R(QQbar(sqrt(1))).parent() Rational Field
This is because QQ(QQbar(sqrt(1)))
does succeed.
sage: 0.1 in R False
As it should be!
sage: R(RDF(0.1)) 1/10
Because QQ(RDF(0.1))
works that way.
sage: R(pi) ValueError: Can't coerce
pi
in any parentReal Field
is a facade for
Because there is not yet any subset of the real numbers handling pi. As soon as there is one, it should be added to the facades and the above will work.
sage: R(ZZ(1)).parent() Rational Field
This is because QQ(ZZ(1))
is the first to succeed (we might add ZZ
to the list of facades).
Which behavior do we want for this?
For me, the current behavior of element construction is close to what it should be. To make things smoother, we might want to modify the QQbar -> QQ
to a QQbar -> AA
. This can be achieved by using a friend complex field on which we could call .real()
. More precisely
def _element_constructor_(self, x):
if parent(x) in self.facade_for():
return x
CC = ComplexField() # the genuine one of course
try:
z = CC(x)
except (ValueError,TypeError):
pass
else:
if z.is_real(): # does not currently work for QQbar
return z.real()
raise ValueError("x not recognized as a real number")
Which interplay with existing representations of real numbers?
This is precisely the question in [comment:23] that you are not helping with by asking it again.
What are the implications in the whole Sage?
Just new features. To be able to do
How do we ensure a smooth transition from the current ill-named
RR
and a genuineRR
corresponding to the field of real numbers?
This question is beyond the scope of this ticket. But see #24457.
Since real numbers are everywhere, we should think about the consequences before being tied with wrong design and the imperative of backward compatibility.
All this to say that we need to have a plan with a boarder view, on which the community agrees.
Note that Ralf opened a ticket on that subject, and since ticket #17713 already has some debates on this subject and a similar purpose, let me suggest to continue the discussion there (so that we collect every input in a single place), and make it a task with appropriate subtickets once we reach a consensus.
To balance, let me add that ticket #17713 was opened 3 years ago, contains three messages and no concrete proposal. It refers to another ticket #15944 that was untouched during 4 years. This ticket on the other hand, started with a concrete proposal and 4 people expressed their opinions. I am about to propose a new version taking into account all comments. We are also not likely to merge it soon as the discussion is going on.
Tickets are also dying because of absence of action. Status-quo is not the way to go either.
Description changed:
---
+++
@@ -1,5 +1,7 @@
-We create a (mostly abstract) class to model the set of real numbers.
+We create (mostly abstract) classes to model the set of complex and real numbers.
follow-ups:
- #24457: rename `sage.rings.real_mpfr.RealField`
- #24458: a useful real lazy field
+
+See also task ticket #17713.
Changed dependencies from #24464, #24465 to #24464, #24465, #24483
Replying to @sagetrac-tmonteil:
sage: R(QQbar(sqrt(2))).parent() Algebraic Real Field sage: R(QQbar(sqrt(1))).parent() Rational Field sage: R(RDF(0.1)) 1/10 sage: R(pi) ValueError: Can't coerce `pi` in any parent `Real Field` is a facade for sage: R(ZZ(1)).parent() Rational Field
All of these could be fixed by simply not letting R
be a Parent
and disallowing R(anything)
. As I said in some comments above, I don't see why R
should be a Parent
(facade or not).
Replying to @videlec:
sage: 0.1 in R False
As it should be!
If you think that 0.1
should not be contained in the field of real numbers, you'll need to justify that better. For me, it is obvious that 0.1
is a real number, such that 0.1 in R
must be True
.
Replying to @sagetrac-tmonteil:
Hence, i think that a collectively approved decision on such subject should happen before code.
+1
It is clear that people support the idea of having a true "real field" object in Sage. However, it is not clear at all what kind of object this should be and how it should be used.
Maybe we should start by thinking about possible use cases for this "real field":
As some placeholder object to denote the field of real numbers, for example as output of QQ.completion(oo)
. This implies that it should be a unique object.
As a Sage analogy to PEP 3141: it should provide a way to ask "is x
a real number" or "is X
a substructure of the reals" or maybe "does parent X
represent the real numbers". Note that Sage already has partial support for PEP 3141 but only for elements (not parents).
Changed dependencies from #24464, #24465, #24483 to #24464, #24465, #24483, #24457
Description changed:
---
+++
@@ -1,7 +1,3 @@
-We create (mostly abstract) classes to model the set of complex and real numbers.
-
-follow-ups:
-- #24457: rename `sage.rings.real_mpfr.RealField`
-- #24458: a useful real lazy field
+We create (mostly abstract) classes to model the set of complex and real numbers as `sage.rings.complex_field.ComplexField` and `sage.rings.real_field.RealField`.
See also task ticket #17713.
Replying to @jdemeyer:
Maybe we should start by thinking about possible use cases for this "real field":
- As some placeholder object to denote the field of real numbers, for example as output of
QQ.completion(oo)
. This implies that it should be a unique object.
Agreed.
- As a Sage analogy to PEP 3141: it should provide a way to ask "is
x
a real number" or "isX
a substructure of the reals" or maybe "does parentX
represent the real numbers". Note that Sage already has partial support for PEP 3141 but only for elements (not parents).
I want to be able distinguish between exact subrings and non-exact approximations. This is for coercion reasons: each exact subring coerces into all non-exact approximations. This is also why I claimed that 0.1 in R
should be False
.
Let me add
As a way to check for is x an exact real number?
and is x a non-exact real number?
. We should specify clearly that isinstance(x, numbers.Real)
means exact real or non-exact real (I take that as given because both issubclass(int, numbers.Real)
and issubclass(float, numbers.Real)
are True
).
As a pointers to all real field implementations (exact subrings and non-exact approximations). In particular it should contain a class factory for all concrete real fields (e.g. the create_RealField
function that is currently used for non-exact approximations).
If you want to ask about exact reals, you should have a 2', where you have a subclass of generic all reals class for the exact reals.
Concerning approximations (like floating point numbers), there are often the three special values NaN
, +inf
and -inf
which are not real numbers (in the mathematical sense). For -inf
and +inf
one can still argue that they approximate very negative and very positive reals. But NaN
is not an approximation of anything. This is one more argument for having RealField()
to mean exact real numbers.
On the other hand, Python numbers.Real
means both floating and exact. Having different semantic for RealField()
and numbers.Real
might be disturbing.
Replying to @videlec:
This is also why I claimed that
0.1 in R
should beFalse
.
I still don't get this. Please elaborate...
Description changed:
---
+++
@@ -1,3 +1,11 @@
We create (mostly abstract) classes to model the set of complex and real numbers as `sage.rings.complex_field.ComplexField` and `sage.rings.real_field.RealField`.
See also task ticket #17713.
+
+Use cases for this new "real field" object:
+
+1. As some placeholder object to denote the field of real numbers, for example as output of `QQ.completion(oo)`. This implies that it should be a unique object.
+
+2. As a Sage analogy to [PEP 3141](https://www.python.org/dev/peps/pep-3141/): it should provide a way to ask "is `x` a real number" or "is `X` a substructure of the reals" or maybe "does parent `X` represent the real numbers". Also, we should be able to ask "is `x` an *exact* or *approximate* real number". Note that Sage already has partial support for PEP 3141 but only for elements (not parents).
+
+3. As a pointers to all real field implementations (exact subrings and non-exact approximations). In particular it [what ???] should contain a class factory for all concrete real fields (e.g. the `create_RealField` function that is currently used for non-exact approximations).
Replying to @videlec:
- As a pointers to all real field implementations (exact subrings and non-exact approximations). In particular it should contain a class factory for all concrete real fields (e.g. the
create_RealField
function that is currently used for non-exact approximations).
What is the it in this last sentence?
Replying to @jdemeyer:
Replying to @videlec:
This is also why I claimed that
0.1 in R
should beFalse
.I still don't get this. Please elaborate...
For me RealField
means the field of real numbers in the mathematical sense together with its exact operations +
, -
, log
, exp
, etc. Floating-point numbers do not respect exactness of operations and for me do not qualify as being real numbers. I agree that you can think of a floating point number in two ways. As an approximation of a real number "m ± 2-e" or as a diadic number "p 2-n". The latter is the actual datastructure but it is mostly useless to think of it this way when doing mathematics. This is moreover how it works in Sage: QQ
coerces into RealField(prec)
and not the contrary even though RealField(prec)
is formally a subset of QQ
.
Replying to @jdemeyer:
Replying to @videlec:
- As a pointers to all real field implementations (exact subrings and non-exact approximations). In particular it should contain a class factory for all concrete real fields (e.g. the
create_RealField
function that is currently used for non-exact approximations).What is the it in this last sentence?
I meant the genuine real field that we are trying to design.
Replying to @videlec:
I meant the genuine real field that we are trying to design.
OK, so what would it mean for a Python object (representing the real field) to "contain a class factory"? Do you want something like
sage: R = RealField()
sage: R.create(prec=53, implementation="mpfr")
Real Floating-point field with 53 bits of precision
or maybe
sage: R = RealField()
sage: R(prec=53, implementation="mpfr")
Real Floating-point field with 53 bits of precision
Description changed:
---
+++
@@ -8,4 +8,4 @@
2. As a Sage analogy to [PEP 3141](https://www.python.org/dev/peps/pep-3141/): it should provide a way to ask "is `x` a real number" or "is `X` a substructure of the reals" or maybe "does parent `X` represent the real numbers". Also, we should be able to ask "is `x` an *exact* or *approximate* real number". Note that Sage already has partial support for PEP 3141 but only for elements (not parents).
-3. As a pointers to all real field implementations (exact subrings and non-exact approximations). In particular it [what ???] should contain a class factory for all concrete real fields (e.g. the `create_RealField` function that is currently used for non-exact approximations).
+3. As a class factory for all concrete real fields (e.g. the `create_RealField` function that is currently used for non-exact approximations).
Replying to @videlec:
For me
RealField
means the field of real numbers in the mathematical sense together with its exact operations+
,-
,log
,exp
, etc. Floating-point numbers do not respect exactness of operations and for me do not qualify as being real numbers.
That point of view is technically mathematically true but also completely useless. Clearly, the real floating-point field is meant to model the real numbers. For technical reasons, the operations are not exact. But that is an implementation detail and not a mathematical property. For practical purposes, it behaves as a field.
I do agree that it makes sense to differentiate between exact real fields and approximate real fields, but both are real fields.
Replying to @jdemeyer:
Replying to @videlec:
For me
RealField
means the field of real numbers in the mathematical sense together with its exact operations+
,-
,log
,exp
, etc. Floating-point numbers do not respect exactness of operations and for me do not qualify as being real numbers.That point of view is technically mathematically true but also completely useless. Clearly, the real floating-point field is meant to model the real numbers.
Indeed!
For technical reasons, the operations are not exact. But that is an implementation detail and not a mathematical property. For practical purposes, it behaves as a field.
It is not associative! Equality dramatically fails! This is not a detail.
I do agree that it makes sense to differentiate between exact real fields and approximate real fields, but both are real fields.
I also agree and IMHO, for consistency with numbers.Real
, the genuine RealField
should be both used for approximate (= projection) and exact (= subset). And this should be very clearly stated.
We create (mostly abstract) classes to model the set of complex and real numbers as
sage.rings.complex_field.ComplexField
andsage.rings.real_field.RealField
.See also task ticket #17713.
Use cases for this new "real field" object:
As some placeholder object to denote the field of real numbers, for example as output of
QQ.completion(oo)
, for domain/codomain of symbolic functions, in manifolds, etc. This implies that it should be a unique object.As a Sage analogy to PEP 3141: it should provide a way to ask "is
x
a real number" or "isX
a substructure of the reals" or maybe "does parentX
represent the real numbers". Also, we should be able to ask "isx
an exact or approximate real number". Note that Sage already has partial support for PEP 3141 but only for elements (not parents).As a class factory for all concrete real fields (e.g. the
create_RealField
function that is currently used for non-exact approximations).Depends on #24464 Depends on #24465 Depends on #24483 Depends on #24457
CC: @rwst @tscrim @egourgoulhon @mjungmath
Component: basic arithmetic
Work Issues: merge conflict
Author: Vincent Delecroix
Branch/Commit: u/rws/24456 @
febfe35
Issue created by migration from https://trac.sagemath.org/ticket/24456