{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Real projective plane $\\mathbb{RP}^2$\n", "\n", "This Jupyter notebook demonstrates some capabilities of SageMath about differentiable manifolds on the example of real projective plane. The corresponding tools have been developed within\n", "the [SageManifolds](https://sagemanifolds.obspm.fr) project." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A version of SageMath at least equal to 7.5 is required to run this notebook:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'SageMath version 9.2, Release Date: 2020-10-24'" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "version()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First we set up the notebook to use LaTeX for rendering outputs:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "%display latex" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Constructing the manifold\n", "We start by declaring the real projective plane as a 2-dimensional differentiable manifold:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/latex": [ "\\begin{math}\n", "\\newcommand{\\Bold}{\\mathbf{#1}}\\mathbb{RP}^2\n", "\\end{math}" ], "text/plain": [ "2-dimensional differentiable manifold RP^2" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "RP2 = Manifold(2, 'RP^2', r'\\mathbb{RP}^2')\n", "RP2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Then we provide $\\mathbb{RP}^2$ with some atlas. A minimal atlas on $\\mathbb{RP}^2$ must have at least three charts. Such an atlas is easy to infer from the common interpretation of $\\mathbb{RP}^2$ as the set of lines of $\\mathbb{R}^3$ passing through the origin $(x,y,z)=(0,0,0)$. Let $U_1$ be the subset of lines that are not contained in the plane $z=0$; this is an open set of $\\mathbb{RP}^2$, so that we declare it as:

" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/latex": [ "\\begin{math}\n", "\\newcommand{\\Bold}{\\mathbf{#1}}U_1\n", "\\end{math}" ], "text/plain": [ "Open subset U_1 of the 2-dimensional differentiable manifold RP^2" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "U1 = RP2.open_subset('U_1')\n", "U1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Any line in $U_1$ is uniquely determined by its intersection with the plane $z=1$. The Cartesian coordinates $(x,y,1)$ of the intersection point lead to an obvious coordinate system $(x_1,y_1)$ on $U_1$ by setting $(x_1,y_1)=(x,y)$:

" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/latex": [ "\\begin{math}\n", "\\newcommand{\\Bold}{\\mathbf{#1}}\\left(U_1,(x_{1}, y_{1})\\right)\n", "\\end{math}" ], "text/plain": [ "Chart (U_1, (x1, y1))" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "X1. = U1.chart()\n", "X1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Note that since we have not specified any coordinate range in the arguments of chart(), the range of $(x_1,y_1)$ is $\\mathbb{R}^2$.

\n", "

Similarly, let $U_2$ be the set of lines through the origin of $\\mathbb{R}^3$ that are not contained in the plane $x=0$. Any line in $U_2$ is uniquely determined by its intersection $(1,y,z)$ with the plane $x=1$, leading to coordinates $(x_2,y_2)=(y,z)$ on $U_2$:

" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/latex": [ "\\begin{math}\n", "\\newcommand{\\Bold}{\\mathbf{#1}}\\left(U_2,(x_{2}, y_{2})\\right)\n", "\\end{math}" ], "text/plain": [ "Chart (U_2, (x2, y2))" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "U2 = RP2.open_subset('U_2')\n", "X2. = U2.chart()\n", "X2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Finally, let $U_3$ be the set of lines through the origin of $\\mathbb{R}^3$ that are not contained in the plane $y=0$. Any line in $U_3$ is uniquely determined by its intersection $(x,1,z)$ with the plane $y=1$, leading to coordinates $(x_3,y_3)=(z,x)$ on $U_3$:

" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/latex": [ "\\begin{math}\n", "\\newcommand{\\Bold}{\\mathbf{#1}}\\left(U_3,(x_{3}, y_{3})\\right)\n", "\\end{math}" ], "text/plain": [ "Chart (U_3, (x3, y3))" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "U3 = RP2.open_subset('U_3')\n", "X3. = U3.chart()\n", "X3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

We declare that the union of the three (overlapping) open domains $U_1$, $U_2$ and $U_3$ is $\\mathbb{RP}^2$:

" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/latex": [ "\\begin{math}\n", "\\newcommand{\\Bold}{\\mathbf{#1}}\\mathbb{RP}^2\n", "\\end{math}" ], "text/plain": [ "2-dimensional differentiable manifold RP^2" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "RP2.declare_union(U1.union(U2), U3)\n", "U1.union(U2).union(U3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

At this stage, three open covers of $\\mathbb{RP}^2$ have been constructed:

" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/latex": [ "\\begin{math}\n", "\\newcommand{\\Bold}{\\mathbf{#1}}\\left[\\left[\\mathbb{RP}^2\\right], \\left[U_1\\cup U_2, U_3\\right], \\left[U_1, U_2, U_3\\right]\\right]\n", "\\end{math}" ], "text/plain": [ "[[2-dimensional differentiable manifold RP^2],\n", " [Open subset U_1_union_U_2 of the 2-dimensional differentiable manifold RP^2,\n", " Open subset U_3 of the 2-dimensional differentiable manifold RP^2],\n", " [Open subset U_1 of the 2-dimensional differentiable manifold RP^2,\n", " Open subset U_2 of the 2-dimensional differentiable manifold RP^2,\n", " Open subset U_3 of the 2-dimensional differentiable manifold RP^2]]" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "RP2.open_covers()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Finally, to fully specify the manifold $\\mathbb{RP}^2$, we give the transition maps between the various charts; the transition map between the charts X1=$(U_1,(x_1,y_1))$ and X2=$(U_2,(x_2,y_2))$ is defined on the set $U_{12} := U_1 \\cap U_2$ of lines through the origin of $\\mathbb{R}^3$ that are neither contained in the plane $x=0$ ($x_1=0$ in $U_1$) nor contained in the plane $z=0$ ($y_2=0$ in $U_2$):

" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/latex": [ "\\begin{math}\n", "\\newcommand{\\Bold}{\\mathbf{#1}}\\left\\{\\begin{array}{lcl} x_{2} & = & \\frac{y_{1}}{x_{1}} \\\\ y_{2} & = & \\frac{1}{x_{1}} \\end{array}\\right.\n", "\\end{math}" ], "text/plain": [ "x2 = y1/x1\n", "y2 = 1/x1" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "X1_to_X2 = X1.transition_map(X2, (y1/x1, 1/x1), intersection_name='U_{12}',\n", " restrictions1= x1!=0, restrictions2= y2!=0)\n", "X1_to_X2.display()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

The inverse of this transition map is easily computed by Sage:

" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/latex": [ "\\begin{math}\n", "\\newcommand{\\Bold}{\\mathbf{#1}}\\left\\{\\begin{array}{lcl} x_{1} & = & \\frac{1}{y_{2}} \\\\ y_{1} & = & \\frac{x_{2}}{y_{2}} \\end{array}\\right.\n", "\\end{math}" ], "text/plain": [ "x1 = 1/y2\n", "y1 = x2/y2" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "X2_to_X1 = X1_to_X2.inverse()\n", "X2_to_X1.display()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

The transition map between the charts X1=$(U_1,(x_1,y_1))$ and X3=$(U_3,(x_3,y_3))$ is defined on the set $U_{13} := U_1 \\cap U_3$ of lines through the origin of $\\mathbb{R}^3$ that are neither contained in the plane $y=0$ ($y_1=0$ in $U_1$) nor contained in the plane $z=0$ ($x_3=0$ in $U_3$):

" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/latex": [ "\\begin{math}\n", "\\newcommand{\\Bold}{\\mathbf{#1}}\\left\\{\\begin{array}{lcl} x_{3} & = & \\frac{1}{y_{1}} \\\\ y_{3} & = & \\frac{x_{1}}{y_{1}} \\end{array}\\right.\n", "\\end{math}" ], "text/plain": [ "x3 = 1/y1\n", "y3 = x1/y1" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "X1_to_X3 = X1.transition_map(X3, (1/y1, x1/y1), intersection_name='U_{13}',\n", " restrictions1= y1!=0, restrictions2= x3!=0)\n", "X1_to_X3.display()" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/latex": [ "\\begin{math}\n", "\\newcommand{\\Bold}{\\mathbf{#1}}\\left\\{\\begin{array}{lcl} x_{1} & = & \\frac{y_{3}}{x_{3}} \\\\ y_{1} & = & \\frac{1}{x_{3}} \\end{array}\\right.\n", "\\end{math}" ], "text/plain": [ "x1 = y3/x3\n", "y1 = 1/x3" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "X3_to_X1 = X1_to_X3.inverse()\n", "X3_to_X1.display()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Finally, the transition map between the charts X2=$(U_2,(x_2,y_2))$ and X3=$(U_3,(x_3,y_3))$ is defined on the set $U_{23} := U_2 \\cap U_3$ of lines through the origin of $\\mathbb{R}^3$ that are neither contained in the plane $y=0$ ($x_2=0$ in $U_2$) nor contained in the plane $x=0$ ($y_3=0$ in $U_3$):

" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/latex": [ "\\begin{math}\n", "\\newcommand{\\Bold}{\\mathbf{#1}}\\left\\{\\begin{array}{lcl} x_{3} & = & \\frac{y_{2}}{x_{2}} \\\\ y_{3} & = & \\frac{1}{x_{2}} \\end{array}\\right.\n", "\\end{math}" ], "text/plain": [ "x3 = y2/x2\n", "y3 = 1/x2" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "X2_to_X3 = X2.transition_map(X3, (y2/x2, 1/x2), intersection_name='U_{23}',\n", " restrictions1= x2!=0, restrictions2= y3!=0)\n", "X2_to_X3.display()" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/latex": [ "\\begin{math}\n", "\\newcommand{\\Bold}{\\mathbf{#1}}\\left\\{\\begin{array}{lcl} x_{2} & = & \\frac{1}{y_{3}} \\\\ y_{2} & = & \\frac{x_{3}}{y_{3}} \\end{array}\\right.\n", "\\end{math}" ], "text/plain": [ "x2 = 1/y3\n", "y2 = x3/y3" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "X3_to_X2 = X2_to_X3.inverse()\n", "X3_to_X2.display()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

At this stage, the manifold $\\mathbb{RP}^2$ is fully constructed. It has been provided with the following atlas:

" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/latex": [ "\\begin{math}\n", "\\newcommand{\\Bold}{\\mathbf{#1}}\\left[\\left(U_1,(x_{1}, y_{1})\\right), \\left(U_2,(x_{2}, y_{2})\\right), \\left(U_3,(x_{3}, y_{3})\\right), \\left(U_{12},(x_{1}, y_{1})\\right), \\left(U_{12},(x_{2}, y_{2})\\right), \\left(U_{13},(x_{1}, y_{1})\\right), \\left(U_{13},(x_{3}, y_{3})\\right), \\left(U_{23},(x_{2}, y_{2})\\right), \\left(U_{23},(x_{3}, y_{3})\\right)\\right]\n", "\\end{math}" ], "text/plain": [ "[Chart (U_1, (x1, y1)),\n", " Chart (U_2, (x2, y2)),\n", " Chart (U_3, (x3, y3)),\n", " Chart (U_{12}, (x1, y1)),\n", " Chart (U_{12}, (x2, y2)),\n", " Chart (U_{13}, (x1, y1)),\n", " Chart (U_{13}, (x3, y3)),\n", " Chart (U_{23}, (x2, y2)),\n", " Chart (U_{23}, (x3, y3))]" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "RP2.atlas()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Note that, in addition to the three chart we have defined, the atlas comprises subcharts on the intersection domains $U_{12}$, $U_{13}$ and $U_{23}$. These charts can be obtained by the method restrict():

" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/latex": [ "\\begin{math}\n", "\\newcommand{\\Bold}{\\mathbf{#1}}\\left(U_{12},(x_{1}, y_{1})\\right)\n", "\\end{math}" ], "text/plain": [ "Chart (U_{12}, (x1, y1))" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "U12 = U1.intersection(U2)\n", "U13 = U1.intersection(U3)\n", "U23 = U2.intersection(U3)\n", "X1.restrict(U12)" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/latex": [ "\\begin{math}\n", "\\newcommand{\\Bold}{\\mathbf{#1}}\\mathrm{True}\n", "\\end{math}" ], "text/plain": [ "True" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "X1.restrict(U12) is RP2.atlas()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

## Non-orientability of $\\mathbb{RP}^2$

\n", "

It is well known that $\\mathbb{RP}^2$ is not an orientable manifold. To illustrate this, let us make an attempt to construct a global non-vanishing 2-form $\\epsilon$ on $\\mathbb{RP}^2$. If we succeed, this would provide a volume form and $\\mathbb{RP}^2$ would be orientable. We start by declaring $\\epsilon$ as a 2-form on $\\mathbb{RP}^2$:

" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2-form eps on the 2-dimensional differentiable manifold RP^2\n" ] } ], "source": [ "eps = RP2.diff_form(2, name='eps', latex_name=r'\\epsilon')\n", "print(eps)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

We set the value of $\\epsilon$ on domain $U_1$ to be $\\mathrm{d}x_1 \\wedge \\mathrm{d}y_1$ by demanding that the component $\\epsilon_{01}$ of $\\epsilon$ with respect to coordinates $(x_1,y_1)$  is one, as follows:

" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/latex": [ "\\begin{math}\n", "\\newcommand{\\Bold}{\\mathbf{#1}}\\left(U_1, \\left(\\frac{\\partial}{\\partial x_{1} },\\frac{\\partial}{\\partial y_{1} }\\right)\\right)\n", "\\end{math}" ], "text/plain": [ "Coordinate frame (U_1, (d/dx1,d/dy1))" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "e1 = X1.frame()\n", "e1" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/latex": [ "\\begin{math}\n", "\\newcommand{\\Bold}{\\mathbf{#1}}\\epsilon = \\mathrm{d} x_{1}\\wedge \\mathrm{d} y_{1}\n", "\\end{math}" ], "text/plain": [ "eps = dx1/\\dy1" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "eps[e1,0,1] = 1\n", "eps.display(e1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

If we ask for the expression of $\\epsilon$ in terms of the coframe $(\\mathrm{d}x_2, \\mathrm{d}y_2)$ associated with the chart X2 on $U_{12} = U_1\\cap U_2$, we get

" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/latex": [ "\\begin{math}\n", "\\newcommand{\\Bold}{\\mathbf{#1}}\\epsilon = \\frac{1}{y_{2}^{3}} \\mathrm{d} x_{2}\\wedge \\mathrm{d} y_{2}\n", "\\end{math}" ], "text/plain": [ "eps = y2^(-3) dx2/\\dy2" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "eps.display(X2.frame().restrict(U12), chart=X2.restrict(U12))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Now, the complement of $U_{12}$ in $U_2$ is defined by $y_2=0$. The above expression shows that it is not possible to extend smoothly $\\epsilon$ to the whole domain $U_2$. We conclude that starting from $\\mathrm{d}x_1\\wedge\\mathrm{d}y_1$ on $U_1$, it is not possible to get a regular non-vanishing 2-form on $\\mathbb{RP}^2$. This of course follows from the fact that $\\mathbb{RP}^2$ is not orientable.

\n", "\n", "

## Steiner map (Roman surface)

\n", "

Let us first define $\\mathbb{R}^3$ as a 3-dimensional manifold, with a single-chart atlas (Cartesian coordinates Y):

" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [], "source": [ "R3 = Manifold(3, 'R^3', r'\\mathbb{R}^3')\n", "Y. = R3.chart()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

The Steiner map is a map $\\mathbb{RP}^2 \\rightarrow \\mathbb{R}^3$ defined as follows:

" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/latex": [ "\\begin{math}\n", "\\newcommand{\\Bold}{\\mathbf{#1}}\\begin{array}{llcl} \\Phi:& \\mathbb{RP}^2 & \\longrightarrow & \\mathbb{R}^3 \\\\ \\mbox{on}\\ U_1 : & \\left(x_{1}, y_{1}\\right) & \\longmapsto & \\left(x, y, z\\right) = \\left(\\frac{y_{1}}{x_{1}^{2} + y_{1}^{2} + 1}, \\frac{x_{1}}{x_{1}^{2} + y_{1}^{2} + 1}, \\frac{x_{1} y_{1}}{x_{1}^{2} + y_{1}^{2} + 1}\\right) \\\\ \\mbox{on}\\ U_2 : & \\left(x_{2}, y_{2}\\right) & \\longmapsto & \\left(x, y, z\\right) = \\left(\\frac{x_{2} y_{2}}{x_{2}^{2} + y_{2}^{2} + 1}, \\frac{y_{2}}{x_{2}^{2} + y_{2}^{2} + 1}, \\frac{x_{2}}{x_{2}^{2} + y_{2}^{2} + 1}\\right) \\\\ \\mbox{on}\\ U_3 : & \\left(x_{3}, y_{3}\\right) & \\longmapsto & \\left(x, y, z\\right) = \\left(\\frac{x_{3}}{x_{3}^{2} + y_{3}^{2} + 1}, \\frac{x_{3} y_{3}}{x_{3}^{2} + y_{3}^{2} + 1}, \\frac{y_{3}}{x_{3}^{2} + y_{3}^{2} + 1}\\right) \\end{array}\n", "\\end{math}" ], "text/plain": [ "Phi: RP^2 --> R^3\n", "on U_1: (x1, y1) |--> (x, y, z) = (y1/(x1^2 + y1^2 + 1), x1/(x1^2 + y1^2 + 1), x1*y1/(x1^2 + y1^2 + 1))\n", "on U_2: (x2, y2) |--> (x, y, z) = (x2*y2/(x2^2 + y2^2 + 1), y2/(x2^2 + y2^2 + 1), x2/(x2^2 + y2^2 + 1))\n", "on U_3: (x3, y3) |--> (x, y, z) = (x3/(x3^2 + y3^2 + 1), x3*y3/(x3^2 + y3^2 + 1), y3/(x3^2 + y3^2 + 1))" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Phi = RP2.diff_map(R3, {(X1,Y): [y1/(1+x1^2+y1^2), x1/(1+x1^2+y1^2), x1*y1/(1+x1^2+y1^2)],\n", " (X2,Y): [x2*y2/(1+x2^2+y2^2), y2/(1+x2^2+y2^2), x2/(1+x2^2+y2^2)],\n", " (X3,Y): [x3/(1+x3^2+y3^2), x3*y3/(1+x3^2+y3^2), y3/(1+x3^2+y3^2)]},\n", " name='Phi', latex_name=r'\\Phi')\n", "Phi.display()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

$\\Phi$ is a topological immersion of $\\mathbb{RP}^2$ into $\\mathbb{R}^3$, but it is not a smooth immersion (contrary to the Apéry map below): its differential is not injective at $(x_1,y_1)=(0,1)$ and $(x_1,y_1)=(1,0)$. The image of $\\Phi$ is a self-intersecting surface of $\\mathbb{R}^3$, called the Roman surface:

" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "