{
 "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 Introduction (Sage days 100, Bonn 2019)\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. When you program in Sage you program in Python. If you\n",
    "know Python you can use it in Sage!\n",
    "\n",
    "There are subtle differences between Sage and Python and we will come\n",
    "back to it.\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 adds 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.<x> = 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": [
    "In sage this concept of base ring or more generally ground set is called\n",
    "a \"parent\"."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "R.<x> = PolynomialRing(ZZ, 'x')\n",
    "p = x^4 + 1\n",
    "p.parent()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Partition([3,2,1]).parent()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Object oriented, autocompletion, documentation, sources\n",
    "\n",
    "Python is an object-oriented language. That means that functions are\n",
    "attached to objects on which they act. For example you would write\n",
    "`14.factor()` rather than `factor(14)`.\n",
    "\n",
    "The SageMath documentation is useful but it is much more efficient to\n",
    "use help directly from the notebook. The three following features are\n",
    "essential.\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"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "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": [
    "## Sage versus Python\n",
    "\n",
    "You should know that even if Sage is built on top of Python, these two\n",
    "languages do not behave exactly the same. To run a cell directly in\n",
    "Python start it with `%%python` as in:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%python\n",
    "print(3^5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "What is the answer to the above command in Sage?\n",
    "\n",
    "To make life of mathematician easier, Sage has a *preparser*: before a\n",
    "command is sent to Python it is transformed. You can call explicitely\n",
    "the preparser on a string to know what it does:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "preparse(\"3^5\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "What does the preparser do to integers? To the operator `^`?\n",
    "\n",
    "You learnt that Python integers and Sage integers are not the same\n",
    "thing!\n",
    "\n",
    "## Some links\n",
    "\n",
    "### The essentials\n",
    "\n",
    "-   The main website: <http://www.sagemath.org/>\n",
    "-   A forum to ask your questions about Sage: <http://ask.sagemath.org>\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): <http://sagebook.gforge.inria.fr/>\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 at\n",
    "<http://doc.sagemath.org/>\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
}