|
330 | 330 |
|
331 | 331 | from sage.categories.fields import Fields
|
332 | 332 | from sage.categories.manifolds import Manifolds
|
| 333 | +from sage.categories.homset import Hom |
333 | 334 | from sage.rings.all import CC
|
334 | 335 | from sage.rings.real_mpfr import RR, RealField_class
|
335 | 336 | from sage.rings.complex_field import ComplexField_class
|
@@ -643,6 +644,10 @@ def __init__(self, n, name, field, structure, ambient=None,
|
643 | 644 | self._zero_scalar_field = self._scalar_field_algebra.zero()
|
644 | 645 | # The unit scalar field:
|
645 | 646 | self._one_scalar_field = self._scalar_field_algebra.one()
|
| 647 | + # Dictionary of sets of morphisms to over manifolds (keys: codomains): |
| 648 | + self._homsets = {} # to be populated by self._Hom_ |
| 649 | + # The identity map on self: |
| 650 | + self._identity_map = Hom(self, self).one() |
646 | 651 |
|
647 | 652 | def _repr_(self):
|
648 | 653 | r"""
|
@@ -1830,6 +1835,297 @@ def one_scalar_field(self):
|
1830 | 1835 |
|
1831 | 1836 | global_options = ManifoldOptions
|
1832 | 1837 |
|
| 1838 | + def _Hom_(self, other, category=None): |
| 1839 | + r""" |
| 1840 | + Construct the set of morphisms (i.e. continuous maps) |
| 1841 | + ``self`` --> ``other``. |
| 1842 | +
|
| 1843 | + INPUT: |
| 1844 | +
|
| 1845 | + - ``other`` -- an open subset of some topological manifold over the |
| 1846 | + same field as ``self`` |
| 1847 | + - ``category`` -- (default: ``None``) not used here (to ensure |
| 1848 | + compatibility with generic hook ``_Hom_``) |
| 1849 | +
|
| 1850 | + OUTPUT: |
| 1851 | +
|
| 1852 | + - the homset Hom(U,V), where U is ``self`` and V is ``other`` |
| 1853 | +
|
| 1854 | + See class |
| 1855 | + :class:`~sage.manifolds.manifold_homset.TopologicalManifoldHomset` |
| 1856 | + for more documentation. |
| 1857 | +
|
| 1858 | + TESTS:: |
| 1859 | +
|
| 1860 | + sage: M = Manifold(2, 'M', structure='topological') |
| 1861 | + sage: N = Manifold(3, 'N', structure='topological') |
| 1862 | + sage: H = M._Hom_(N); H |
| 1863 | + Set of Morphisms from 2-dimensional topological manifold M to |
| 1864 | + 3-dimensional topological manifold N in Category of manifolds over |
| 1865 | + Real Field with 53 bits of precision |
| 1866 | +
|
| 1867 | + The result is cached:: |
| 1868 | +
|
| 1869 | + sage: H is Hom(M, N) |
| 1870 | + True |
| 1871 | +
|
| 1872 | + """ |
| 1873 | + if other not in self._homsets: |
| 1874 | + self._homsets[other] = self._structure.homset(self, other) |
| 1875 | + return self._homsets[other] |
| 1876 | + |
| 1877 | + def continuous_map(self, codomain, coord_functions=None, chart1=None, |
| 1878 | + chart2=None, name=None, latex_name=None): |
| 1879 | + r""" |
| 1880 | + Define a continuous map between the current topological manifold |
| 1881 | + and another topological manifold over the same topological field. |
| 1882 | +
|
| 1883 | + See :class:`~sage.manifolds.continuous_map.ContinuousMap` for a |
| 1884 | + complete documentation. |
| 1885 | +
|
| 1886 | + INPUT: |
| 1887 | +
|
| 1888 | + - ``codomain`` -- the map's codomain (must be an instance |
| 1889 | + of :class:`TopologicalManifold`) |
| 1890 | + - ``coord_functions`` -- (default: ``None``) if not ``None``, must be |
| 1891 | + either |
| 1892 | +
|
| 1893 | + - (i) a dictionary of |
| 1894 | + the coordinate expressions (as lists (or tuples) of the |
| 1895 | + coordinates of the image expressed in terms of the coordinates of |
| 1896 | + the considered point) with the pairs of charts (chart1, chart2) |
| 1897 | + as keys (chart1 being a chart on ``self`` and chart2 a chart on |
| 1898 | + ``codomain``) |
| 1899 | + - (ii) a single coordinate expression in a given pair of charts, the |
| 1900 | + latter being provided by the arguments ``chart1`` and ``chart2`` |
| 1901 | +
|
| 1902 | + In both cases, if the dimension of the codomain is 1, a single |
| 1903 | + coordinate expression can be passed instead of a tuple with a single |
| 1904 | + element |
| 1905 | + - ``chart1`` -- (default: ``None``; used only in case (ii) above) chart |
| 1906 | + on the current manifold defining the start coordinates involved in |
| 1907 | + ``coord_functions`` for case (ii); if none is provided, the |
| 1908 | + coordinates are assumed to refer to the manifold's default chart |
| 1909 | + - ``chart2`` -- (default: ``None``; used only in case (ii) above) chart |
| 1910 | + on ``codomain`` defining the target coordinates involved in |
| 1911 | + ``coord_functions`` for case (ii); if none is provided, the |
| 1912 | + coordinates are assumed to refer to the default chart of ``codomain`` |
| 1913 | + - ``name`` -- (default: ``None``) name given to the continuous |
| 1914 | + map |
| 1915 | + - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the |
| 1916 | + continuous map; if none is provided, the LaTeX symbol is set to |
| 1917 | + ``name`` |
| 1918 | +
|
| 1919 | + OUTPUT: |
| 1920 | +
|
| 1921 | + - the continuous map, as an instance of |
| 1922 | + :class:`~sage.manifolds.continuous_map.ContinuousMap` |
| 1923 | +
|
| 1924 | + EXAMPLES: |
| 1925 | +
|
| 1926 | + A continuous map between an open subset of `S^2` covered by regular |
| 1927 | + spherical coordinates and `\RR^3`:: |
| 1928 | +
|
| 1929 | + sage: M = Manifold(2, 'S^2', structure='topological') |
| 1930 | + sage: U = M.open_subset('U') |
| 1931 | + sage: c_spher.<th,ph> = U.chart(r'th:(0,pi):\theta ph:(0,2*pi):\phi') |
| 1932 | + sage: N = Manifold(3, 'R^3', latex_name=r'\RR^3', structure='topological') |
| 1933 | + sage: c_cart.<x,y,z> = N.chart() # Cartesian coord. on R^3 |
| 1934 | + sage: Phi = U.continuous_map(N, (sin(th)*cos(ph), sin(th)*sin(ph), cos(th)), |
| 1935 | + ....: name='Phi', latex_name=r'\Phi') |
| 1936 | + sage: Phi |
| 1937 | + Continuous map Phi from the Open subset U of the 2-dimensional topological manifold S^2 to the 3-dimensional topological manifold R^3 |
| 1938 | +
|
| 1939 | + The same definition, but with a dictionary with pairs of charts as |
| 1940 | + keys (case (i) above):: |
| 1941 | +
|
| 1942 | + sage: Phi1 = U.continuous_map(N, |
| 1943 | + ....: {(c_spher, c_cart): (sin(th)*cos(ph), sin(th)*sin(ph), cos(th))}, |
| 1944 | + ....: name='Phi', latex_name=r'\Phi') |
| 1945 | + sage: Phi1 == Phi |
| 1946 | + True |
| 1947 | +
|
| 1948 | + The continuous map acting on a point:: |
| 1949 | +
|
| 1950 | + sage: p = U.point((pi/2, pi)) ; p |
| 1951 | + Point on the 2-dimensional topological manifold S^2 |
| 1952 | + sage: Phi(p) |
| 1953 | + Point on the 3-dimensional topological manifold R^3 |
| 1954 | + sage: Phi(p).coord(c_cart) |
| 1955 | + (-1, 0, 0) |
| 1956 | + sage: Phi1(p) == Phi(p) |
| 1957 | + True |
| 1958 | +
|
| 1959 | + See the documentation of class |
| 1960 | + :class:`~sage.manifolds.continuous_map.ContinuousMap` for more |
| 1961 | + examples. |
| 1962 | +
|
| 1963 | + """ |
| 1964 | + homset = Hom(self, codomain) |
| 1965 | + if coord_functions is None: |
| 1966 | + coord_functions = {} |
| 1967 | + if not isinstance(coord_functions, dict): |
| 1968 | + # Turn coord_functions into a dictionary: |
| 1969 | + if chart1 is None: |
| 1970 | + chart1 = self._def_chart |
| 1971 | + elif chart1 not in self._atlas: |
| 1972 | + raise ValueError("{} is not a chart ".format(chart1) + |
| 1973 | + "defined on the {}".format(self)) |
| 1974 | + if chart2 is None: |
| 1975 | + chart2 = codomain._def_chart |
| 1976 | + elif chart2 not in codomain._atlas: |
| 1977 | + raise ValueError("{} is not a chart ".format(chart2) + |
| 1978 | + " defined on the {}".format(codomain)) |
| 1979 | + coord_functions = {(chart1, chart2): coord_functions} |
| 1980 | + return homset(coord_functions, name=name, latex_name=latex_name) |
| 1981 | + |
| 1982 | + def homeomorphism(self, codomain, coord_functions=None, chart1=None, |
| 1983 | + chart2=None, name=None, latex_name=None): |
| 1984 | + r""" |
| 1985 | + Define a homeomorphism between the current manifold and another one. |
| 1986 | +
|
| 1987 | + See :class:`~sage.manifolds.continuous_map.ContinuousMap` for a |
| 1988 | + complete documentation. |
| 1989 | +
|
| 1990 | + INPUT: |
| 1991 | +
|
| 1992 | + - ``codomain`` -- codomain of the homeomorphism (must be an instance |
| 1993 | + of :class:`TopologicalManifold`) |
| 1994 | + - ``coord_functions`` -- (default: ``None``) if not ``None``, must be |
| 1995 | + either |
| 1996 | +
|
| 1997 | + - (i) a dictionary of |
| 1998 | + the coordinate expressions (as lists (or tuples) of the |
| 1999 | + coordinates of the image expressed in terms of the coordinates of |
| 2000 | + the considered point) with the pairs of charts (chart1, chart2) |
| 2001 | + as keys (chart1 being a chart on ``self`` and chart2 a chart on |
| 2002 | + ``codomain``) |
| 2003 | + - (ii) a single coordinate expression in a given pair of charts, the |
| 2004 | + latter being provided by the arguments ``chart1`` and ``chart2`` |
| 2005 | +
|
| 2006 | + In both cases, if the dimension of the codomain is 1, a single |
| 2007 | + coordinate expression can be passed instead of a tuple with |
| 2008 | + a single element |
| 2009 | + - ``chart1`` -- (default: ``None``; used only in case (ii) above) chart |
| 2010 | + on the current manifold defining the start coordinates involved in |
| 2011 | + ``coord_functions`` for case (ii); if none is provided, the |
| 2012 | + coordinates are assumed to refer to the manifold's default chart |
| 2013 | + - ``chart2`` -- (default: ``None``; used only in case (ii) above) chart |
| 2014 | + on ``codomain`` defining the target coordinates involved in |
| 2015 | + ``coord_functions`` for case (ii); if none is provided, the |
| 2016 | + coordinates are assumed to refer to the default chart of ``codomain`` |
| 2017 | + - ``name`` -- (default: ``None``) name given to the homeomorphism |
| 2018 | + - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the |
| 2019 | + homeomorphism; if none is provided, the LaTeX symbol is set to |
| 2020 | + ``name`` |
| 2021 | +
|
| 2022 | + OUTPUT: |
| 2023 | +
|
| 2024 | + - the homeomorphism, as an instance of |
| 2025 | + :class:`~sage.manifolds.continuous_map.ContinuousMap` |
| 2026 | +
|
| 2027 | + EXAMPLE: |
| 2028 | +
|
| 2029 | + Homeomorphism between the open unit disk in `\RR^2` and `\RR^2`:: |
| 2030 | +
|
| 2031 | + sage: forget() # for doctests only |
| 2032 | + sage: M = Manifold(2, 'M', structure='topological') # the open unit disk |
| 2033 | + sage: c_xy.<x,y> = M.chart('x:(-1,1) y:(-1,1)') # Cartesian coord on M |
| 2034 | + sage: c_xy.add_restrictions(x^2+y^2<1) |
| 2035 | + sage: N = Manifold(2, 'N', structure='topological') # R^2 |
| 2036 | + sage: c_XY.<X,Y> = N.chart() # canonical coordinates on R^2 |
| 2037 | + sage: Phi = M.homeomorphism(N, [x/sqrt(1-x^2-y^2), y/sqrt(1-x^2-y^2)], |
| 2038 | + ....: name='Phi', latex_name=r'\Phi') |
| 2039 | + sage: Phi |
| 2040 | + Homeomorphism Phi from the 2-dimensional topological manifold M to |
| 2041 | + the 2-dimensional topological manifold N |
| 2042 | + sage: Phi.display() |
| 2043 | + Phi: M --> N |
| 2044 | + (x, y) |--> (X, Y) = (x/sqrt(-x^2 - y^2 + 1), y/sqrt(-x^2 - y^2 + 1)) |
| 2045 | +
|
| 2046 | + The inverse homeomorphism:: |
| 2047 | +
|
| 2048 | + sage: Phi^(-1) |
| 2049 | + Homeomorphism Phi^(-1) from the 2-dimensional topological |
| 2050 | + manifold N to the 2-dimensional topological manifold M |
| 2051 | + sage: (Phi^(-1)).display() |
| 2052 | + Phi^(-1): N --> M |
| 2053 | + (X, Y) |--> (x, y) = (X/sqrt(X^2 + Y^2 + 1), Y/sqrt(X^2 + Y^2 + 1)) |
| 2054 | +
|
| 2055 | + See the documentation of class |
| 2056 | + :class:`~sage.manifolds.continuous_map.ContinuousMap` for more |
| 2057 | + examples. |
| 2058 | +
|
| 2059 | + """ |
| 2060 | + homset = Hom(self, codomain) |
| 2061 | + if coord_functions is None: |
| 2062 | + coord_functions = {} |
| 2063 | + if not isinstance(coord_functions, dict): |
| 2064 | + # Turn coord_functions into a dictionary: |
| 2065 | + if chart1 is None: |
| 2066 | + chart1 = self._def_chart |
| 2067 | + elif chart1 not in self._atlas: |
| 2068 | + raise ValueError("{} is not a chart ".format(chart1) + |
| 2069 | + "defined on the {}".format(self)) |
| 2070 | + if chart2 is None: |
| 2071 | + chart2 = codomain._def_chart |
| 2072 | + elif chart2 not in codomain._atlas: |
| 2073 | + raise ValueError("{} is not a chart ".format(chart2) + |
| 2074 | + " defined on the {}".format(codomain)) |
| 2075 | + coord_functions = {(chart1, chart2): coord_functions} |
| 2076 | + return homset(coord_functions, name=name, latex_name=latex_name, |
| 2077 | + is_isomorphism=True) |
| 2078 | + |
| 2079 | + def identity_map(self): |
| 2080 | + r""" |
| 2081 | + Identity map of the manifold. |
| 2082 | +
|
| 2083 | + The identity map of a topological manifold `M` is the trivial |
| 2084 | + homeomorphism |
| 2085 | +
|
| 2086 | + .. MATH:: |
| 2087 | +
|
| 2088 | + \begin{array}{cccc} |
| 2089 | + \mathrm{Id}_M: & M & \longrightarrow & M \\ |
| 2090 | + & p & \longmapsto & p |
| 2091 | + \end{array} |
| 2092 | +
|
| 2093 | + See :class:`~sage.manifolds.continuous_map.ContinuousMap` for a |
| 2094 | + complete documentation. |
| 2095 | +
|
| 2096 | + OUTPUT: |
| 2097 | +
|
| 2098 | + - the identity map, as an instance of |
| 2099 | + :class:`~sage.manifolds.continuous_map.ContinuousMap` |
| 2100 | +
|
| 2101 | + EXAMPLE: |
| 2102 | +
|
| 2103 | + Identity map of a complex manifold:: |
| 2104 | +
|
| 2105 | + sage: M = Manifold(2, 'M', structure='topological', field='complex') |
| 2106 | + sage: X.<x,y> = M.chart() |
| 2107 | + sage: id = M.identity_map(); id |
| 2108 | + Identity map Id_M of the Complex 2-dimensional topological manifold M |
| 2109 | + sage: id.parent() |
| 2110 | + Set of Morphisms from Complex 2-dimensional topological manifold M |
| 2111 | + to Complex 2-dimensional topological manifold M in Category of |
| 2112 | + manifolds over Complex Field with 53 bits of precision |
| 2113 | + sage: id.display() |
| 2114 | + Id_M: M --> M |
| 2115 | + (x, y) |--> (x, y) |
| 2116 | +
|
| 2117 | + The identity map acting on a point:: |
| 2118 | +
|
| 2119 | + sage: p = M((1+I, 3-I), name='p'); p |
| 2120 | + Point p on the Complex 2-dimensional topological manifold M |
| 2121 | + sage: id(p) |
| 2122 | + Point p on the Complex 2-dimensional topological manifold M |
| 2123 | + sage: id(p) == p |
| 2124 | + True |
| 2125 | +
|
| 2126 | + """ |
| 2127 | + return self._identity_map |
| 2128 | + |
1833 | 2129 | ##############################################################################
|
1834 | 2130 | ## Constructor function
|
1835 | 2131 |
|
|
0 commit comments