Ejemplo n.º 1
0
    def __init__(self,
                 n,
                 name,
                 metric_name='g',
                 signature=None,
                 base_manifold=None,
                 diff_degree=infinity,
                 latex_name=None,
                 metric_latex_name=None,
                 start_index=0,
                 category=None,
                 unique_tag=None):
        r"""
        Construct a pseudo-Riemannian manifold.

        TESTS::

            sage: M = Manifold(4, 'M', structure='pseudo-Riemannian',
            ....:              signature=0)
            sage: M
            4-dimensional pseudo-Riemannian manifold M
            sage: type(M)
            <class 'sage.manifolds.differentiable.pseudo_riemannian.PseudoRiemannianManifold_with_category'>
            sage: X.<w,x,y,z> = M.chart()
            sage: M.metric()
            Pseudo-Riemannian metric g on the 4-dimensional pseudo-Riemannian manifold M
            sage: TestSuite(M).run()

        """
        if base_manifold and not isinstance(base_manifold,
                                            PseudoRiemannianManifold):
            raise TypeError("the argument 'base_manifold' must be a " +
                            "pseudo-Riemannian manifold")
        if signature is None or signature == n:
            structure = RiemannianStructure()
        elif signature == n - 2 or signature == 2 - n:
            structure = LorentzianStructure()
        else:
            structure = PseudoRiemannianStructure()
        DifferentiableManifold.__init__(self,
                                        n,
                                        name,
                                        'real',
                                        structure,
                                        base_manifold=base_manifold,
                                        diff_degree=diff_degree,
                                        latex_name=latex_name,
                                        start_index=start_index,
                                        category=category)
        self._metric = None  # to be initialized by metric()
        self._metric_signature = signature
        if not isinstance(metric_name, str):
            raise TypeError("{} is not a string".format(metric_name))
        self._metric_name = metric_name
        if metric_latex_name is None:
            self._metric_latex_name = self._metric_name
        else:
            if not isinstance(metric_latex_name, str):
                raise TypeError("{} is not a string".format(metric_latex_name))
            self._metric_latex_name = metric_latex_name
Ejemplo n.º 2
0
    def __init__(self,
                 n,
                 name,
                 metric_name=None,
                 signature=None,
                 base_manifold=None,
                 diff_degree=infinity,
                 latex_name=None,
                 metric_latex_name=None,
                 start_index=0,
                 category=None,
                 unique_tag=None):
        r"""
        Construct a degenerate manifold.

        TESTS::

            sage: M = Manifold(3, 'M', structure='degenerate_metric')
            sage: M
            3-dimensional degenerate_metric manifold M
            sage: type(M)
            <class 'sage.manifolds.differentiable.degenerate.DegenerateManifold_with_category'>
            sage: X.<x,y,z> = M.chart()
            sage: M.metric()
            degenerate metric g on the 3-dimensional degenerate_metric manifold M
            sage: TestSuite(M).run()

        """
        if base_manifold and not isinstance(base_manifold, DegenerateManifold):
            raise TypeError("the argument 'base_manifold' must be a " +
                            "Degenerate manifold")
        structure = DegenerateStructure()
        DifferentiableManifold.__init__(self,
                                        n,
                                        name,
                                        'real',
                                        structure,
                                        base_manifold=base_manifold,
                                        diff_degree=diff_degree,
                                        latex_name=latex_name,
                                        start_index=start_index,
                                        category=category)
        self._metric = None  # to be initialized by metric()
        self._metric_signature = signature
        if metric_name is None:
            metric_name = 'g'
        elif not isinstance(metric_name, str):
            raise TypeError("{} is not a string".format(metric_name))
        self._metric_name = metric_name
        if metric_latex_name is None:
            self._metric_latex_name = self._metric_name
        else:
            if not isinstance(metric_latex_name, str):
                raise TypeError("{} is not a string".format(metric_latex_name))
            self._metric_latex_name = metric_latex_name
Ejemplo n.º 3
0
    def __init__(self, L, name, **kwds):
        r"""
        Initialize ``self``.

        TESTS::

            sage: L = lie_algebras.Heisenberg(QQ, 2)
            sage: G = L.lie_group()
            sage: TestSuite(G).run()
        """
        required_cat = LieAlgebras(L.base_ring()).FiniteDimensional()
        required_cat = required_cat.WithBasis().Nilpotent()
        if L not in required_cat:
            raise TypeError("L needs to be a finite dimensional nilpotent "
                            "Lie algebra with basis")
        self._lie_algebra = L

        R = L.base_ring()
        category = kwds.pop('category', None)
        category = LieGroups(R).or_subcategory(category)
        if isinstance(R, RealField_class):
            structure = RealDifferentialStructure()
        else:
            structure = DifferentialStructure()

        DifferentiableManifold.__init__(self,
                                        L.dimension(),
                                        name,
                                        R,
                                        structure,
                                        category=category)

        # initialize exponential coordinates of the first kind
        basis_strs = [str(X) for X in L.basis()]
        split = list(zip(*[s.split('_') for s in basis_strs]))
        if len(split) == 2 and all(sk == split[0][0] for sk in split[0]):
            self._var_indexing = split[1]
        else:
            self._var_indexing = [str(k) for k in range(L.dimension())]
        variables = ' '.join('x_%s' % k for k in self._var_indexing)
        self._Exp1 = self.chart(variables)

        # compute a symbolic formula for the group law
        L_SR = _symbolic_lie_algebra_copy(L)
        n = L.dimension()
        a, b = (tuple(var('%s_%d' % (s, j)) for j in range(n))
                for s in ['a', 'b'])
        self._group_law_vars = (a, b)
        bch = L_SR.bch(L_SR.from_vector(a), L_SR.from_vector(b), L.step())
        self._group_law = vector(SR, (zk.expand() for zk in bch.to_vector()))
Ejemplo n.º 4
0
    def __init__(self, n, name, metric_name='g', signature=None, ambient=None,
                 diff_degree=infinity, latex_name=None,
                 metric_latex_name=None, start_index=0, category=None,
                 unique_tag=None):
        r"""
        Construct a pseudo-Riemannian manifold.

        TESTS::

            sage: M = Manifold(4, 'M', structure='pseudo-Riemannian',
            ....:              signature=0)
            sage: M
            4-dimensional pseudo-Riemannian manifold M
            sage: type(M)
            <class 'sage.manifolds.differentiable.pseudo_riemannian.PseudoRiemannianManifold_with_category'>
            sage: X.<w,x,y,z> = M.chart()
            sage: M.metric()
            Pseudo-Riemannian metric g on the 4-dimensional pseudo-Riemannian manifold M
            sage: TestSuite(M).run()

        """
        if ambient and not isinstance(ambient, PseudoRiemannianManifold):
            raise TypeError("the argument 'ambient' must be a " +
                            "pseudo-Riemannian manifold")
        if signature is None or signature == n:
            structure = RiemannianStructure()
        elif signature == n-2 or signature == 2-n:
            structure = LorentzianStructure()
        else:
            structure = PseudoRiemannianStructure()
        DifferentiableManifold.__init__(self, n, name, 'real', structure,
                                        ambient=ambient,
                                        diff_degree=diff_degree,
                                        latex_name=latex_name,
                                        start_index=start_index,
                                        category=category)
        self._metric = None # to be initialized by metric()
        self._metric_signature = signature
        if not isinstance(metric_name, str):
            raise TypeError("{} is not a string".format(metric_name))
        self._metric_name = metric_name
        if metric_latex_name is None:
            self._metric_latex_name = self._metric_name
        else:
            if not isinstance(metric_latex_name, str):
                raise TypeError("{} is not a string".format(metric_latex_name))
            self._metric_latex_name = metric_latex_name
Ejemplo n.º 5
0
    def __init__(self, L, name, **kwds):
        r"""
        Initialize ``self``.

        TESTS::

            sage: L = lie_algebras.Heisenberg(QQ, 2)
            sage: G = L.lie_group()
            sage: TestSuite(G).run()
        """
        required_cat = LieAlgebras(L.base_ring()).FiniteDimensional()
        required_cat = required_cat.WithBasis().Nilpotent()
        if L not in required_cat:
            raise TypeError("L needs to be a finite dimensional nilpotent "
                            "Lie algebra with basis")
        self._lie_algebra = L

        R = L.base_ring()
        category = kwds.pop('category', None)
        category = LieGroups(R).or_subcategory(category)
        if isinstance(R, RealField_class):
            structure = RealDifferentialStructure()
        else:
            structure = DifferentialStructure()

        DifferentiableManifold.__init__(self, L.dimension(), name, R,
                                        structure, category=category)

        # initialize exponential coordinates of the first kind
        basis_strs = [str(X) for X in L.basis()]
        split = list(zip(*[s.split('_') for s in basis_strs]))
        if len(split) == 2 and all(sk == split[0][0] for sk in split[0]):
            self._var_indexing = split[1]
        else:
            self._var_indexing = [str(k) for k in range(L.dimension())]
        variables = ' '.join('x_%s' % k for k in self._var_indexing)
        self._Exp1 = self.chart(variables)

        # compute a symbolic formula for the group law
        L_SR = _symbolic_lie_algebra_copy(L)
        n = L.dimension()
        a, b = (tuple(var('%s_%d' % (s, j)) for j in range(n))
                for s in ['a', 'b'])
        self._group_law_vars = (a, b)
        bch = L_SR.bch(L_SR.from_vector(a), L_SR.from_vector(b), L.step())
        self._group_law = vector(SR, (zk.expand() for zk in bch.to_vector()))
    def __init__(self,
                 n,
                 name,
                 field,
                 structure,
                 ambient=None,
                 base_manifold=None,
                 diff_degree=infinity,
                 latex_name=None,
                 start_index=0,
                 category=None,
                 unique_tag=None):
        r"""
        Construct a submanifold of a differentiable manifold.

        EXAMPLES::

            sage: M = Manifold(3, 'M')
            sage: N = Manifold(2, 'N', ambient=M)
            sage: N
            2-dimensional differentiable submanifold N embedded in 3-dimensional
             differentiable manifold M

        """
        DifferentiableManifold.__init__(self,
                                        n,
                                        name,
                                        field,
                                        structure,
                                        base_manifold=base_manifold,
                                        diff_degree=diff_degree,
                                        latex_name=latex_name,
                                        start_index=start_index,
                                        category=category)
        TopologicalSubmanifold.__init__(self,
                                        n,
                                        name,
                                        field,
                                        structure,
                                        ambient=ambient,
                                        base_manifold=base_manifold,
                                        category=category)
Ejemplo n.º 7
0
    def __init__(self,
                 n,
                 name,
                 field,
                 structure,
                 ambient=None,
                 base_manifold=None,
                 diff_degree=infinity,
                 latex_name=None,
                 start_index=0,
                 category=None,
                 unique_tag=None):
        r"""
        Construct a submanifold of a differentiable manifold.

        TESTS::

            sage: M = Manifold(3, 'M')
            sage: N = Manifold(2, 'N', ambient=M)
            sage: N
            2-dimensional differentiable submanifold N immersed in the
             3-dimensional differentiable manifold M
            sage: S = Manifold(2, 'S', latex_name=r'\Sigma', ambient=M,
            ....:              start_index=1)
            sage: latex(S)
            \Sigma
            sage: S.start_index()
            1

        """
        DifferentiableManifold.__init__(self,
                                        n,
                                        name,
                                        field,
                                        structure,
                                        base_manifold=base_manifold,
                                        diff_degree=diff_degree,
                                        latex_name=latex_name,
                                        start_index=start_index,
                                        category=category)
        self._init_immersion(ambient=ambient)
Ejemplo n.º 8
0
    def metric(self,
               name=None,
               signature=None,
               latex_name=None,
               dest_map=None):
        r"""
        Return the metric giving the pseudo-Riemannian structure to the
        manifold, or define a new metric tensor on the manifold.

        INPUT:

        - ``name`` -- (default: ``None``) name given to the metric; if
          ``name`` is ``None`` or matches the name of the metric defining the
          pseudo-Riemannian structure of ``self``, the latter metric is
          returned
        - ``signature`` -- (default: ``None``; ignored if ``name`` is ``None``)
          signature `S` of the metric as a single integer: `S = n_+ - n_-`,
          where `n_+` (resp. `n_-`) is the number of positive terms (resp.
          number of negative terms) in any diagonal writing of the metric
          components; if ``signature`` is not provided, `S` is set to the
          manifold's dimension (Riemannian signature)
        - ``latex_name`` -- (default: ``None``; ignored if ``name`` is ``None``)
          LaTeX symbol to denote the metric; if ``None``, it is formed from
          ``name``
        - ``dest_map`` -- (default: ``None``; ignored if ``name`` is ``None``)
          instance of
          class :class:`~sage.manifolds.differentiable.diff_map.DiffMap`
          representing the destination map `\Phi:\ U \rightarrow M`, where `U`
          is the current manifold; if ``None``, the identity map is assumed
          (case of a metric tensor field *on* `U`)

        OUTPUT:

        - instance of
          :class:`~sage.manifolds.differentiable.metric.PseudoRiemannianMetric`

        EXAMPLES:

        Metric of a 3-dimensional Riemannian manifold::

            sage: M = Manifold(3, 'M', structure='Riemannian', start_index=1)
            sage: X.<x,y,z> = M.chart()
            sage: g = M.metric(); g
            Riemannian metric g on the 3-dimensional Riemannian manifold M

        The metric remains to be initialized, for instance by setting its
        components in the coordinate frame associated to the chart ``X``::

            sage: g[1,1], g[2,2], g[3,3] = 1, 1, 1
            sage: g.display()
            g = dx*dx + dy*dy + dz*dz

        Alternatively, the metric can be initialized from a given field of
        nondegenerate symmetric bilinear forms; we may create the former
        object by::

            sage: X.coframe()
            Coordinate coframe (M, (dx,dy,dz))
            sage: dx, dy, dz = X.coframe()[1], X.coframe()[2], X.coframe()[3]
            sage: b = dx*dx + dy*dy + dz*dz
            sage: b
            Field of symmetric bilinear forms dx*dx+dy*dy+dz*dz on the
             3-dimensional Riemannian manifold M

        We then use the metric method
        :meth:`~sage.manifolds.differentiable.metric.PseudoRiemannianMetric.set`
        to make ``g`` being equal to ``b`` as a symmetric tensor field of
        type ``(0,2)``::

            sage: g.set(b)
            sage: g.display()
            g = dx*dx + dy*dy + dz*dz

        Another metric can be defined on ``M`` by specifying a metric name
        distinct from that chosen at the creation of the manifold (which
        is ``g`` by default, but can be changed thanks to the keyword
        ``metric_name`` in :func:`~sage.manifolds.manifold.Manifold`)::

            sage: h = M.metric('h'); h
            Riemannian metric h on the 3-dimensional Riemannian manifold M
            sage: h[1,1], h[2,2], h[3,3] = 1+y^2, 1+z^2, 1+x^2
            sage: h.display()
            h = (y^2 + 1) dx*dx + (z^2 + 1) dy*dy + (x^2 + 1) dz*dz

        The metric tensor ``h`` is distinct from the metric entering in the
        definition of the Riemannian manifold ``M``::

            sage: h is M.metric()
            False

        while we have of course::

            sage: g is M.metric()
            True

        Providing the same name as the manifold's default metric returns the
        latter::

            sage: M.metric('g') is M.metric()
            True

        In the present case (``M`` is diffeomorphic to `\RR^3`), we can even
        create a Lorentzian metric on ``M``::

            sage: h = M.metric('h', signature=1); h
            Lorentzian metric h on the 3-dimensional Riemannian manifold M

        """
        if name is None or name == self._metric_name:
            # Default metric associated with the manifold
            if self._metric is None:
                if self._manifold is not self and self._manifold._metric is not None:
                    # case of an open subset with a metric already defined on
                    # the ambient manifold:
                    self._metric = self._manifold._metric.restrict(self)
                else:
                    # creation from scratch:
                    self._metric = DifferentiableManifold.metric(
                        self,
                        self._metric_name,
                        signature=self._metric_signature,
                        latex_name=self._metric_latex_name)
            return self._metric
        # Metric distinct from the default one: it is created by the method
        # metric of the superclass for generic differentiable manifolds:
        return DifferentiableManifold.metric(self,
                                             name,
                                             signature=signature,
                                             latex_name=latex_name,
                                             dest_map=dest_map)
Ejemplo n.º 9
0
    def __init__(self,
                 lower,
                 upper,
                 ambient_interval=None,
                 name=None,
                 latex_name=None,
                 coordinate=None,
                 names=None,
                 start_index=0):
        r"""
        Construct an open interval.

        TESTS::

            sage: I = OpenInterval(-1,1); I
            Real interval (-1, 1)
            sage: TestSuite(I).run(skip='_test_elements')  # pickling of elements fails
            sage: J = OpenInterval(-oo, 2); J
            Real interval (-Infinity, 2)
            sage: TestSuite(J).run(skip='_test_elements')  # pickling of elements fails

        """
        if latex_name is None:
            if name is None:
                latex_name = r"\left({}, {}\right)".format(
                    latex(lower), latex(upper))
            else:
                latex_name = name
        if name is None:
            name = "({}, {})".format(lower, upper)
        if ambient_interval is None:
            ambient_manifold = None
        else:
            if not isinstance(ambient_interval, OpenInterval):
                raise TypeError(
                    "the argument ambient_interval must be an open interval")
            ambient_manifold = ambient_interval.manifold()
        field = 'real'
        structure = RealDifferentialStructure()
        DifferentiableManifold.__init__(self,
                                        1,
                                        name,
                                        field,
                                        structure,
                                        base_manifold=ambient_manifold,
                                        latex_name=latex_name,
                                        start_index=start_index)
        if ambient_interval is None:
            if coordinate is None:
                if names is None:
                    coordinate = 't'
                else:
                    coordinate = names[0]
            self._canon_chart = self.chart(coordinates=coordinate)
            t = self._canon_chart[start_index]
        else:
            if lower < ambient_interval.lower_bound():
                raise ValueError("the lower bound is smaller than that of " +
                                 "the containing interval")
            if upper > ambient_interval.upper_bound():
                raise ValueError("the upper bound is larger than that of " +
                                 "the containing interval")
            self._supersets.update(ambient_interval._supersets)
            for sd in ambient_interval._supersets:
                sd._subsets.add(self)
            ambient_interval._top_subsets.add(self)
            t = ambient_interval.canonical_coordinate()
        if lower != minus_infinity:
            if upper != infinity:
                restrictions = [t > lower, t < upper]
            else:
                restrictions = t > lower
        else:
            if upper != infinity:
                restrictions = t < upper
            else:
                restrictions = None
        if ambient_interval is None:
            if restrictions is not None:
                self._canon_chart.add_restrictions(restrictions)
        else:
            self._canon_chart = ambient_interval.canonical_chart().restrict(
                self, restrictions=restrictions)
        self._lower = lower
        self._upper = upper
Ejemplo n.º 10
0
    def metric(self, name=None, signature=None, latex_name=None,
               dest_map=None):
        r"""
        Return the metric giving the pseudo-Riemannian structure to the
        manifold, or define a new metric tensor on the manifold.

        INPUT:

        - ``name`` -- (default: ``None``) name given to the metric; if
          ``name`` is ``None`` or matches the name of the metric defining the
          pseudo-Riemannian structure of ``self``, the latter metric is
          returned
        - ``signature`` -- (default: ``None``; ignored if ``name`` is ``None``)
          signature `S` of the metric as a single integer: `S = n_+ - n_-`,
          where `n_+` (resp. `n_-`) is the number of positive terms (resp.
          number of negative terms) in any diagonal writing of the metric
          components; if ``signature`` is not provided, `S` is set to the
          manifold's dimension (Riemannian signature)
        - ``latex_name`` -- (default: ``None``; ignored if ``name`` is ``None``)
          LaTeX symbol to denote the metric; if ``None``, it is formed from
          ``name``
        - ``dest_map`` -- (default: ``None``; ignored if ``name`` is ``None``)
          instance of
          class :class:`~sage.manifolds.differentiable.diff_map.DiffMap`
          representing the destination map `\Phi:\ U \rightarrow M`, where `U`
          is the current manifold; if ``None``, the identity map is assumed
          (case of a metric tensor field *on* `U`)

        OUTPUT:

        - instance of
          :class:`~sage.manifolds.differentiable.metric.PseudoRiemannianMetric`

        EXAMPLES:

        Metric of a 3-dimensional Riemannian manifold::

            sage: M = Manifold(3, 'M', structure='Riemannian', start_index=1)
            sage: X.<x,y,z> = M.chart()
            sage: g = M.metric(); g
            Riemannian metric g on the 3-dimensional Riemannian manifold M

        The metric remains to be initialized, for instance by setting its
        components in the coordinate frame associated to the chart ``X``::

            sage: g[1,1], g[2,2], g[3,3] = 1, 1, 1
            sage: g.display()
            g = dx*dx + dy*dy + dz*dz

        Alternatively, the metric can be initialized from a given field of
        nondegenerate symmetric bilinear forms; we may create the former
        object by::

            sage: X.coframe()
            Coordinate coframe (M, (dx,dy,dz))
            sage: dx, dy, dz = X.coframe()[1], X.coframe()[2], X.coframe()[3]
            sage: b = dx*dx + dy*dy + dz*dz
            sage: b
            Field of symmetric bilinear forms dx*dx+dy*dy+dz*dz on the
             3-dimensional Riemannian manifold M

        We then use the metric method
        :meth:`~sage.manifolds.differentiable.metric.PseudoRiemannianMetric.set`
        to make ``g`` being equal to ``b`` as a symmetric tensor field of
        type ``(0,2)``::

            sage: g.set(b)
            sage: g.display()
            g = dx*dx + dy*dy + dz*dz

        Another metric can be defined on ``M`` by specifying a metric name
        distinct from that chosen at the creation of the manifold (which
        is ``g`` by default, but can be changed thanks to the keyword
        ``metric_name`` in :func:`~sage.manifolds.manifold.Manifold`)::

            sage: h = M.metric('h'); h
            Riemannian metric h on the 3-dimensional Riemannian manifold M
            sage: h[1,1], h[2,2], h[3,3] = 1+y^2, 1+z^2, 1+x^2
            sage: h.display()
            h = (y^2 + 1) dx*dx + (z^2 + 1) dy*dy + (x^2 + 1) dz*dz

        The metric tensor ``h`` is distinct from the metric entering in the
        definition of the Riemannian manifold ``M``::

            sage: h is M.metric()
            False

        while we have of course::

            sage: g is M.metric()
            True

        Providing the same name as the manifold's default metric returns the
        latter::

            sage: M.metric('g') is M.metric()
            True

        In the present case (``M`` is diffeomorphic to `\RR^3`), we can even
        create a Lorentzian metric on ``M``::

            sage: h = M.metric('h', signature=1); h
            Lorentzian metric h on the 3-dimensional Riemannian manifold M

        """
        if name is None or name == self._metric_name:
            # Default metric associated with the manifold
            if self._metric is None:
                if self._manifold is not self and self._manifold._metric is not None:
                    # case of an open subset with a metric already defined on
                    # the ambient manifold:
                    self._metric = self._manifold._metric.restrict(self)
                else:
                    # creation from scratch:
                    self._metric = DifferentiableManifold.metric(self,
                                           self._metric_name,
                                           signature=self._metric_signature,
                                           latex_name=self._metric_latex_name)
            return self._metric
        # Metric distinct from the default one: it is created by the method
        # metric of the superclass for generic differentiable manifolds:
        return DifferentiableManifold.metric(self, name, signature=signature,
                                             latex_name=latex_name,
                                             dest_map=dest_map)
Ejemplo n.º 11
0
    def __init__(self, lower, upper, ambient=None,
                 name=None, latex_name=None,
                 coordinate=None, names=None, start_index=0):
        r"""
        Construct an open interval.

        TESTS::

            sage: I = OpenInterval(-1,1); I
            Real interval (-1, 1)
            sage: TestSuite(I).run(skip='_test_elements')  # pickling of elements fails
            sage: J = OpenInterval(-oo, 2); J
            Real interval (-Infinity, 2)
            sage: TestSuite(J).run(skip='_test_elements')  # pickling of elements fails

        """
        if latex_name is None:
            if name is None:
                latex_name = r"\left({}, {}\right)".format(latex(lower), latex(upper))
            else:
                latex_name = name
        if name is None:
            name = "({}, {})".format(lower, upper)
        if ambient is None:
            ambient_manifold = None
        else:
            if not isinstance(ambient, OpenInterval):
                raise TypeError("the argument ambient must be an open interval")
            ambient_manifold = ambient.manifold()
        field = 'real'
        structure = RealDifferentialStructure()
        DifferentiableManifold.__init__(self, 1, name, field, structure,
                                        ambient=ambient_manifold,
                                        latex_name=latex_name,
                                        start_index=start_index)
        if ambient is None:
            if coordinate is None:
                if names is None:
                    coordinate = 't'
                else:
                    coordinate = names[0]
            self._canon_chart = self.chart(coordinates=coordinate)
            t = self._canon_chart[start_index]
        else:
            if lower < ambient.lower_bound():
                raise ValueError("the lower bound is smaller than that of "
                                 + "the containing interval")
            if upper > ambient.upper_bound():
                raise ValueError("the upper bound is larger than that of "
                                 + "the containing interval")
            self._supersets.update(ambient._supersets)
            for sd in ambient._supersets:
                sd._subsets.add(self)
            ambient._top_subsets.add(self)
            t = ambient.canonical_coordinate()
        if lower != minus_infinity:
            if upper != infinity:
                restrictions = [t > lower, t < upper]
            else:
                restrictions = t > lower
        else:
            if upper != infinity:
                restrictions = t < upper
            else:
                restrictions = None
        if ambient is None:
            if restrictions is not None:
                self._canon_chart.add_restrictions(restrictions)
        else:
            self._canon_chart = ambient.canonical_chart().restrict(self,
                                                     restrictions=restrictions)
        self._lower = lower
        self._upper = upper