{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "$$\n", "\\def\\CC{\\bf C}\n", "\\def\\QQ{\\bf Q}\n", "\\def\\RR{\\bf R}\n", "\\def\\ZZ{\\bf Z}\n", "\\def\\NN{\\bf N}\n", "$$\n", "# Sage demo: Introduction (Grenoble 2018)\n", "\n", "[Sage (or SageMath)](http://sagemath.org) is an open source software\n", "(GPL-licensed) for mathematics which interfaces many softwares and\n", "libraries, e.g.:\n", "\n", "- [PARI/GP](http://pari.math.u-bordeaux.fr/) (number theory),\n", "- [GAP](http://www.gap-system.org/) (group theory),\n", "- [Maxima](http://maxima.sourceforge.net/) (symbolic calculus),\n", "- The SciPy suite ([numpy](http://www.numpy.org/),\n", " [scipy](http://www.scipy.org/),\n", " [matplotlib](http://matplotlib.org/))\n", "- [GMP](https://gmplib.org/) (C library for arbitrary precision\n", " integers)\n", "- [MPFR](http://www.mpfr.org/) (C library arbitrary precision floating\n", " point numbers)\n", "- [NTL](http://www.shoup.net/ntl/) (C++ library for number theory)\n", "- and [many more](http://www.sagemath.org/links-components.html)\n", "\n", "## Python/Ipython interface\n", "\n", "Sage is based on the [Python](http://www.python.org) language, which is\n", "very popular (web programming, graphical interaces, scripts, ...) and\n", "easy to learn.\n", "\n", "### Python is an expressive langage\n", "\n", "$\\Big\\{17n\\ \\Big|\\ n \\in \\{0,1,\\ldots, 9\\}\\text{ and }n\\text{ is odd}\\Big\\}$" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "S = {17*n for n in range(10) if n%2 == 1}\n", "S" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "124 in S" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sum(S)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "{3*i for i in S}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Sage add some mathematical objects and functions" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "8324074213.factor()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m = matrix(ZZ, 3, 3, [0,3,-2,1,4,3,0,0,1])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m.eigenvalues()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m.inverse()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As in mathematics, the base ring on which an object is defined matters:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "R. = PolynomialRing(ZZ, 'x')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "R" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "P = 6*x^4 + 6*x^3 - 6*x^2 - 12*x - 12\n", "P.factor()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "P2 = P.change_ring(QQ)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "P2.factor()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "P3 = P.change_ring(AA) # AA = field of real algebraic numbers" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "P3.factor()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "P4 = P.change_ring(QQbar) # QQbar = field of complex algebraic numbers" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "P4.factor()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Object oriented, autocompletion, documentation, sources\n", "\n", "Python is an object-oriented language. Sage notebook rely on this to\n", "ease its use:\n", "\n", "- autocomplation with the <TAB> key\n", "- acces to the documentation with \"?\"\n", "- acces to the source code with \"??\"\n", "\n", "Computing the integral of a symbolic function:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "f(x) = sin(x)^2 -sin(x)\n", "f\n", "f.in" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exercice:** Draw the Petersen graph. Which algorithm is used to\n", "compute the vertex cover of this graph ?" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "G = grap" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# edit here" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "G.vertex" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# edit here" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Calculator\n", "\n", "Integration (symbolic, numeric and certified numeric)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "integral(e^(-x^2), x, -Infinity, Infinity)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "integral(1/sqrt(1+x^3), x, 0, 1)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "numerical_integral(1/sqrt(1+x^3), 0, 1)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "R = ComplexBallField(128)\n", "R.integral(lambda x,_: 1/(1+x^3).sqrt(), 0, 1)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "R = ComplexBallField(1024)\n", "R.integral(lambda x,_: 1/(1+x^3).sqrt(), 0, 1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Roots:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "f(x) = x^5 - 1/3*x^2 - 7*sin(2*x) + 1" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "plot(f, xmin=-2, xmax=2)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "r1 = find_root(f,-2,-1)\n", "r1" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "r2 = find_root(f,0,1)\n", "r2" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "r3 = find_root(f,1,2)\n", "r3" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "plot(f, xmin=-2, xmax=2) + point2d([(r1,0),(r2,0),(r3,0)], pointsize=50, color='red')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Latex:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "M = Matrix(QQ, [[1,2,3],[4,5,6],[7,8,9]]); M" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "latex(M)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "M.parent()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "latex(M.parent())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Graphics:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x, y = SR.var('x,y')\n", "plot3d(sin(x-y)*y*cos(x), (x,-3,3), (y,-3,3))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Interaction:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "var('x')\n", "@interact\n", "def g(f=sin(x)-cos(x)^2, c=0.0, n=(1..30),\n", " xinterval=range_slider(-10, 10, 1, default=(-8,8), label=\"x-interval\"),\n", " yinterval=range_slider(-50, 50, 1, default=(-3,3), label=\"y-interval\")):\n", " x0 = c\n", " degree = n\n", " xmin,xmax = xinterval\n", " ymin,ymax = yinterval\n", " p = plot(f, xmin, xmax, thickness=4)\n", " dot = point((x0,f(x=x0)),pointsize=80,rgbcolor=(1,0,0))\n", " ft = f.taylor(x,x0,degree)\n", " pt = plot(ft, xmin, xmax, color='red', thickness=2, fill=f)\n", " show(dot + p + pt, ymin=ymin, ymax=ymax, xmin=xmin, xmax=xmax)\n", " pretty_print(html('$f(x)\\;=\\;%s$'%latex(f)))\n", " pretty_print(html('$P_{%s}(x)\\;=\\;%s+R_{%s}(x)$'%(degree,latex(ft),degree)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Extra packages for geometry and dynamics\n", "\n", "There are several packages built on top of Sage dedicated to geometry\n", "and dynamics. Let us mention\n", "\n", "- [flipper](http://flipper.readthedocs.io/en/latest/): mapping classes\n", "- [snappy](https://www.math.uic.edu/t3m/SnapPy/): 3-d hyperbolic\n", " geometry\n", "- [surface\\_dynamics](http://www.labri.fr/perso/vdelecro/flatsurf_sage.html):\n", " interval exchange transformations, origamis and more\n", "- [flatsurf](https://github.com/videlec/sage-flatsurf): translation\n", " surfaces (affine transformation, linear flow, etc)\n", "\n", "With flipper you can check the braid relation (Javier Aramayona course).\n", "The surface $S_{2,1}$ we use is depicted on the picture below\n", "\n", "![image](S_2_1.svg)\n", "\n", "Here is how to play with the Dehn-twist around the curves $a$ and $b$" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import flipper" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "S = flipper.load('S_2_1')\n", "a = S.mapping_class('a')\n", "b = S.mapping_class('b')\n", "a*b*a == b*a*b" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "With snappy installed you can investigate 3-dimensional hyperbolic\n", "manifolds. It comes with an extensive database of them. Here we compute\n", "some invariantes of the manifold \"m015\" from the database." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import snappy " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "M = snappy.Manifold(\"m015\")\n", "M" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "M.cusp_info()\n", "M.alexander_polynomial()\n", "M.volume()\n", "M.complex_volume()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Flipper can be used to construct mapping tori of pseudo-Anosov\n", "homeomorphism and send them to snappy for further analysis" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import flipper\n", "import snappy" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "S = flipper.load('S_2_1')\n", "a = S.mapping_class('a')\n", "b = S.mapping_class('b')\n", "C = S.mapping_class('C')\n", "d = S.mapping_class('d')\n", "f = a * b * C * d\n", "f.nielsen_thurston_type()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "M = snappy.Manifold(f.bundle())\n", "M.volume()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "With surface\\_dynamics installed you can play with origamis" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import surface_dynamics" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "o = surface_dynamics.Origami('(1,2)', '(1,3)')\n", "o.stratum()\n", "o.plot()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "V = o.veech_group()\n", "V\n", "print V.nu2(), V.nu3(), V.ncusps()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "V.farey_symbol().fundamental_domain()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Finally, flatsurf allows you to construct translation surface from\n", "polygons and play with translation flow. Below we construct saddle\n", "connections on the double pentagon" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import flatsurf" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "S = flatsurf.translation_surfaces.veech_double_n_gon(5)\n", "S.plot()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sc = S.saddle_connections(20)\n", "S.plot() + sum(s.plot(color='red') for s in sc)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Flipper pseudo-Anosov can also be sent to flatsurf as follows" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import flipper\n", "import flatsurf" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "S = flipper.load('S_2_1')\n", "a = S.mapping_class('a')\n", "b = S.mapping_class('b')\n", "C = S.mapping_class('C')\n", "d = S.mapping_class('d')\n", "f = a * b * C * d\n", "S = flatsurf.translation_surfaces.from_flipper(f)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Some links\n", "\n", "### The essentials\n", "\n", "- The main website: \n", "- A forum to ask your questions about Sage: \n", "- A book \"Calcul math\u00e9matique avec Sage\"/\"Computational Mathematics\n", " with SageMath\"/\"Rechnen mit Sage\", a book about Sage (in french,\n", " english and german): \n", "\n", "### Introductory tutorials\n", "\n", "If you just start with Sage, it is a good idea to work on the 6\n", "Programming worksheets (\"First steps with Sage\", \"Learn about for\n", "loops\", etc).\n", "\n", "You can also have a look at the Sage documentation. These documents are\n", "part of Sage and you can access them from the Jupyter notebook by\n", "clicking on \"Help\" -> \"Thematic Tutorials\". They are also available\n", "at \n", "\n", "------------------------------------------------------------------------\n", "\n", "Authors \n", "- Thierry Monteil\n", "- Vincent Delecroix\n", "\n", "License \n", "CC BY-SA 3.0" ] } ], "metadata": { "kernelspec": { "display_name": "sagemath", "name": "sagemath" } }, "nbformat": 4, "nbformat_minor": 2 }