Opened 11 months ago
Last modified 5 months ago
#31241 new enhancement
Forgetful Functors for Manifold Objects
Reported by: | gh-mjungmath | Owned by: | |
---|---|---|---|
Priority: | major | Milestone: | sage-9.5 |
Component: | manifolds | Keywords: | |
Cc: | tscrim, egourgoulhon, mkoeppe | Merged in: | |
Authors: | Reviewers: | ||
Report Upstream: | N/A | Work issues: | |
Branch: | Commit: | ||
Dependencies: | #31247 | Stopgaps: |
Description (last modified by )
It would be nice to allow forgetful functors for manifolds. In particular:
- differentiable manifolds -> topological manifolds
- (Pseudo-)Riemannian manifolds -> differentiable manifolds (not a category yet)
- topological manifolds -> sets (?)
and probably even more. The last point, if getting to work somehow, might also be useful and/or should be seen in view of #30832.
At the moment, we have the following behavior (which could be seen as a bug):
sage: from sage.categories.functor import ForgetfulFunctor sage: from sage.categories.manifolds import Manifolds sage: F = ForgetfulFunctor(Manifolds(RR).Differentiable(), Manifolds(RR).Topological()) sage: M = Manifold(2, 'M') sage: F(M) 2-dimensional differentiable manifold M
Change History (33)
comment:1 Changed 11 months ago by
- Description modified (diff)
comment:2 Changed 11 months ago by
- Description modified (diff)
comment:3 Changed 11 months ago by
- Description modified (diff)
comment:4 Changed 11 months ago by
- Cc tscrim egourgoulhon mkoeppe added
comment:5 Changed 11 months ago by
- Description modified (diff)
comment:6 Changed 11 months ago by
- Description modified (diff)
comment:7 Changed 11 months ago by
- Summary changed from Forgetful Functors for Manifolds to Forgetful Functors for Manifold Objects
comment:8 Changed 11 months ago by
- Description modified (diff)
comment:9 follow-up: ↓ 10 Changed 11 months ago by
comment:10 in reply to: ↑ 9 ; follow-up: ↓ 13 Changed 11 months ago by
Replying to tscrim:
I am a little hesitant to call it a bug because it still has that structure once it goes through the functor. The problem is the mutability and that you can make it leave the corresponding category. Now you could implement something specific that handles an instance of
Manifold
. Although I feel that getting something of this level of generality would be hard. I think you are probably better off implementing a mechanism in theManifold
class itself.
Agreed. Calling that, one could make a function in OpenInterval
returning an element of RealSet
. But wait, the forgetful functor to sets works differently, right?
The approach I had in mind is as simple as that: new instance of the desired kind and copy charts. Where do you think may problems occour?
comment:11 Changed 11 months ago by
I have the feeling that ForgetfulFunctor
does not work how it supposed to be, already on a deeper level. Right now, it calls the following code from Functor
:
def _apply_functor(self, x): """ Apply the functor to an object of ``self``'s domain. NOTE: Each subclass of :class:`Functor` should overload this method. By default, this method coerces into the codomain, without checking whether the argument belongs to the domain. TESTS:: sage: from sage.categories.functor import Functor sage: F = Functor(FiniteFields(),Fields()) sage: F._apply_functor(ZZ) Rational Field """ return self.__codomain(x)
Here, __codomain
should be the destination category. However, the call function of a category is treated as a coercion:
def __call__(self, x, *args, **opts): """ Construct an object in this category from the data in ``x``, or throw ``TypeError`` or ``NotImplementedError``. If ``x`` is readily in ``self`` it is returned unchanged. Categories wishing to extend this minimal behavior should implement :meth:`._call_`. EXAMPLES:: sage: Rings()(ZZ) Integer Ring """ if x in self: return x return self._call_(x, *args, **opts)
as the following note in sage/categories/sets_cat.py
indicates, too:
def _call_(self, X, enumerated_set=False): r""" Construct an object in this category from the data ``X``. INPUT: - ``X`` -- an object to be converted into a set - ``enumerated_set`` -- if set to ``True`` and the input is either a Python tuple or a Python list then the output will be a finite enumerated set. EXAMPLES:: sage: Sets()(ZZ) Integer Ring sage: Sets()([1, 2, 3]) {1, 2, 3} sage: S = Sets()([1, 2, 3]); S.category() Category of finite sets sage: S = Sets()([1, 2, 3], enumerated_set=True); S.category() Category of facade finite enumerated sets .. NOTE:: Using ``Sets()(A)`` used to implement some sort of forgetful functor into the ``Sets()`` category. This feature has been removed, because it was not consistent with the semantic of :meth:`Category.__call__`. Proper forgetful functors will eventually be implemented, with another syntax. """ if enumerated_set and type(X) in (tuple, list, range): from sage.categories.enumerated_sets import EnumeratedSets return EnumeratedSets()(X) from sage.sets.set import Set return Set(X)
Proper forgetful functors will eventually be implemented, with another syntax. It seems, this hasn't been done so far.
That's worth another ticket, isn't it?
comment:12 Changed 11 months ago by
- Dependencies set to #31247
comment:13 in reply to: ↑ 10 ; follow-ups: ↓ 14 ↓ 17 Changed 11 months ago by
Replying to gh-mjungmath:
Replying to tscrim:
I am a little hesitant to call it a bug because it still has that structure once it goes through the functor. The problem is the mutability and that you can make it leave the corresponding category. Now you could implement something specific that handles an instance of
Manifold
. Although I feel that getting something of this level of generality would be hard. I think you are probably better off implementing a mechanism in theManifold
class itself.Agreed. Calling that, one could make a function in
OpenInterval
returning an element ofRealSet
. But wait, the forgetful functor to sets works differently, right?The approach I had in mind is as simple as that: new instance of the desired kind and copy charts. Where do you think may problems occour?
Something you could do is implement the corresponding _call_
in the appropriate subcategories of Manifolds
to handle the corresponding transferring of data. Although this probably would be a lot easier once there is a way to copy manifolds and reconstruct them, which I still need to do as part of the pickling fix... There is just a lot of data that needs to be carefully preserved and constructed ideally using the construction methods already in place. That is where bugs will likely occur. There are many ways to implement this that have various pros and cons, you just need to decide on which one you want.
comment:14 in reply to: ↑ 13 Changed 11 months ago by
comment:15 Changed 11 months ago by
Okay, if I recall correctly, #31247 is not a bug, just simply not realistic. Instead, we can overwrite __call__
(double underscore!) for the special case of manifolds.
comment:16 Changed 10 months ago by
- Milestone changed from sage-9.3 to sage-9.4
Setting new milestone based on a cursory review of ticket status, priority, and last modification date.
comment:17 in reply to: ↑ 13 Changed 7 months ago by
Replying to tscrim:
Something you could do is implement the corresponding
_call_
in the appropriate subcategories ofManifolds
to handle the corresponding transferring of data. Although this probably would be a lot easier once there is a way to copy manifolds and reconstruct them, which I still need to do as part of the pickling fix... There is just a lot of data that needs to be carefully preserved and constructed ideally using the construction methods already in place. That is where bugs will likely occur. There are many ways to implement this that have various pros and cons, you just need to decide on which one you want.
Foremost charts, transition maps and their domains need to be copied since they encode the manifold's topology. I don't think that more data are necessary, except for the name and the dimension.
Is there a ticket devoted to pickling of manifolds yet?
comment:18 follow-up: ↓ 19 Changed 6 months ago by
See also: discussion in https://trac.sagemath.org/ticket/31877#comment:10
comment:19 in reply to: ↑ 18 Changed 6 months ago by
Replying to mkoeppe:
See also: discussion in https://trac.sagemath.org/ticket/31877#comment:10
I tend to say that things are different for manifold objects. Sometimes you really want to work in a genuine weaker structure, for example to impose new charts that have continuous transition maps instead of differentiable ones.
comment:20 Changed 6 months ago by
I think you can boil it down to the following. In contrast to rings like ZZ
or QQ
, where elements are immutable objects, manifold objects can dynamically be extended. Now, the extension highly depends on the context (topological, differentiable, semi-Riemannian).
comment:21 follow-up: ↓ 22 Changed 6 months ago by
As I mentioned in #31877, the manifold is not as special as you want it to be. It can be provided more information, but it is not something that is mutable. Subsequently, you have genuinely different objects for topological and differentiable on the same underlying set if you have different maximal atlases. Applying the forgetful functor, you would have the same maximal atlas, which means the differentiable structure would still be there.
comment:22 in reply to: ↑ 21 Changed 6 months ago by
Replying to tscrim:
As I mentioned in #31877, the manifold is not as special as you want it to be. It can be provided more information, but it is not something that is mutable. Subsequently, you have genuinely different objects for topological and differentiable on the same underlying set if you have different maximal atlases. Applying the forgetful functor, you would have the same maximal atlas, which means the differentiable structure would still be there.
Sure, starting with a differential manifold and applying the forgetful functor to it, a new instance must be constructed, particularly an instance of TopologicalManifold
. It should come with the "same" charts (different instances of course). Then you can add new charts dynamically, e.g. continuous but not differentiable, to the implementation. This is where the dynamical nature of manifolds comes into play.
That is at least how I would think the forgetful functor might be used in this case.
comment:23 Changed 6 months ago by
And I didn't say the manifold itself was mutable. I said its objects were.
comment:24 follow-up: ↓ 25 Changed 6 months ago by
You are confusing the notion of mutable and dynamic and forgetting that a manifold is defined by its objects (e.g., charts). If you have a differentiable manifold M
and apply the forgetful functor to it, you get the same manifold M
back with the same maximal atlas. If you then "add" something that makes it not a differentiable manifold, then you actually have a different manifold because you have a different maximal atlas. So you are actually creating a copy with some of the initial information the same, but you then give information that your copy is different than what you started with. Having initial information is a programming concept, not a mathematical one.
comment:25 in reply to: ↑ 24 ; follow-up: ↓ 26 Changed 6 months ago by
Replying to tscrim:
You are confusing the notion of mutable and dynamic and forgetting that a manifold is defined by its objects (e.g., charts). If you have a differentiable manifold
M
and apply the forgetful functor to it, you get the same manifoldM
back with the same maximal atlas. If you then "add" something that makes it not a differentiable manifold, then you actually have a different manifold because you have a different maximal atlas. So you are actually creating a copy with some of the initial information the same, but you then give information that your copy is different than what you started with. Having initial information is a programming concept, not a mathematical one.
Mathematically this is wrong. As soon as you apply the forgetful functor from differentiable manifolds to topological manifolds, the maximal atlas changes accordingly. In particular, the maximal atlas now consists of all charts that are continuously compatible w.r.t. to all charts in the differentiable structure.
That is exactly the punchline: adding a non-compatible chart (in the differentiable sense) which is still countinously compatible would corrupt the differentiable structure, but keep the maximal atlas of the topological manifold intact.
comment:26 in reply to: ↑ 25 ; follow-up: ↓ 27 Changed 6 months ago by
Replying to gh-mjungmath:
Replying to tscrim:
You are confusing the notion of mutable and dynamic and forgetting that a manifold is defined by its objects (e.g., charts). If you have a differentiable manifold
M
and apply the forgetful functor to it, you get the same manifoldM
back with the same maximal atlas. If you then "add" something that makes it not a differentiable manifold, then you actually have a different manifold because you have a different maximal atlas. So you are actually creating a copy with some of the initial information the same, but you then give information that your copy is different than what you started with. Having initial information is a programming concept, not a mathematical one.Mathematically this is wrong. As soon as you apply the forgetful functor from differentiable manifolds to topological manifolds, the maximal atlas changes accordingly. In particular, the maximal atlas now consists of all charts that are continuously compatible w.r.t. to all charts in the differentiable structure.
You're wrong. Otherwise the category of differentiable manifolds is not a subcategory of topological manifolds. So there would be no forgetful functor. Alternatively, you have a covering of your manifold by charts with maps to open subsets of R^{n} that are diffeomorphic. The fact this is a covering forces any other chart to also be a diffeomorphism by the transition functions. Your maximal atlas cannot change under the forgetful functor.
That is exactly the punchline: adding a non-compatible chart (in the differentiable sense) which is still countinously compatible would corrupt the differentiable structure, but keep the maximal atlas of the topological manifold intact.
Which gives you a new distinct mathematical object. You cannot add information to the manifold by the forgetful functor. In the implementation here, you are not adding or changing the information, only "discovering" more.
comment:27 in reply to: ↑ 26 ; follow-up: ↓ 28 Changed 6 months ago by
Replying to tscrim:
You're wrong. Otherwise the category of differentiable manifolds is not a subcategory of topological manifolds. So there would be no forgetful functor.
Why not? The differentiable structure is a subset of the maximal topological atlas, and the maximal atlas is uniquely determined by the differentiable structure, so I don't see any problems here.
In any case, it would be nice to copy a differentiable manifold in terms of a topological manifold. The forgetful functor would do the job in the mathematical sense.
comment:28 in reply to: ↑ 27 ; follow-up: ↓ 29 Changed 6 months ago by
Replying to gh-mjungmath:
Replying to tscrim:
You're wrong. Otherwise the category of differentiable manifolds is not a subcategory of topological manifolds. So there would be no forgetful functor.
Why not? The differentiable structure is a subset of the maximal topological atlas, and the maximal atlas is uniquely determined by the differentiable structure, so I don't see any problems here.
Because you have a genuinely different manifold when your maximal atlas changes. This is not the result of applying the forgetful functor as an embedding of subcategories.
You also have to be careful that this is up to equality, not isomorphism. For example, there are infinitely many smooth structures you can place upon R^{4}, so they are not equivalent (i.e., diffeomorphic) in the category of smooth manifolds. However, applying the forgetful functor to each of these do not result in the same (in the equality sense) copy of R^{4}, but they are all isomorphic (now here homeomorphic) in the category of topological manifolds.
For a very concrete example of the above, the above is analogous to the groups C_{4} and C_{2} x C_{2}. They are equivalent as sets (i.e., same cardinality) but not as groups.
In any case, it would be nice to copy a differentiable manifold in terms of a topological manifold. The forgetful functor would do the job in the mathematical sense.
See above. It is mathematically wrong to not obtain a differentiable manifold from the forgetful functor if you want differentiable manifolds to be a subcategory of topological manifolds. I don't see how the category of differentiable manifolds is not a subcategory of topological manifolds (in the mathematical sense of a subcategory). If you want to call this the forgetful functor, you need to prove to me that the maximal atlas actually changes.
comment:29 in reply to: ↑ 28 Changed 6 months ago by
Replying to tscrim:
Because you have a genuinely different manifold when your maximal atlas changes. This is not the result of applying the forgetful functor as an embedding of subcategories.
Okay, I think we can see it as follows. A topological manifold comes equipped with a maximal topological atlas. This atlas contains all information about the topology and local Euclideanness.
To impose a differentiable structure, we add an additional atlas, namely the maximal differentiable atlas. So in a way, we can say that a differentiable manifold is endowed with two atlases. However, it turns out that the topological atlas is not needed because it can be recovered from the differentiable atlas.
Now, when we apply the forgetful functor, we simply forget about the differentiable atlas, and what remains is the maximal topological atlas.
So you were right when you said "the atlas does not change". I suppose I was just extremely sloppy here. Does that resolve some things?
comment:30 follow-up: ↓ 31 Changed 6 months ago by
Ye. Thus what you really want is a way to create a copy of the current data, but with the category changed. This is similar to the change_ring()
method of matrices.
comment:31 in reply to: ↑ 30 Changed 6 months ago by
Replying to tscrim:
Ye. Thus what you really want is a way to create a copy of the current data, but with the category changed. This is similar to the
change_ring()
method of matrices.
Mh. Not really, right? A differentiable manifold is an instance of DifferentiableManifold
. If we want to work with that manifold in terms of a topological manifold, we must turn (or rather copy) it into an instance of TopologicalManifold
. Changing the category or a structure attribute alone wouldn't do the job, no?
comment:32 Changed 6 months ago by
Yea, perhaps I was a little imprecise. I meant change the necessary information in the copy.
comment:33 Changed 5 months ago by
- Milestone changed from sage-9.4 to sage-9.5
I am a little hesitant to call it a bug because it still has that structure once it goes through the functor. The problem is the mutability and that you can make it leave the corresponding category. Now you could implement something specific that handles an instance of
Manifold
. Although I feel that getting something of this level of generality would be hard. I think you are probably better off implementing a mechanism in theManifold
class itself.