{ "cells": [ { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# OpenDreamKit: a SageMath-oriented debriefing\n", "\n", "Sage Day 109, May 28th of 2020\n", "\n", "\n", "\n", "Nicolas M. Thiéry
\n", "LRI, Université Paris Sud\n", "


\n", "\n", "\n", "\n", "
\n", "\n", "\n", "" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## A personal perspective\n", "\n", "Note: just one of the many threads that came together to create OpenDreamKit" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "### 1999: a PhD in algebraic combinatorics\n", "\n", "#### Observations\n", "- So many cool tools around; but incompatible\n", "- The need, opportunity, and struggle to share\n", "- The lack of resources to develop code\n", "- E.g. GAP federating a community in group theory" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "notes" } }, "outputs": [], "source": [ "- From the beginning a big fan of software packages like GAP, Singular, Pari\n", " demonstrated that, with a few dedicated leaders, whole communities\n", " of researchers could get together, and share their work, and build\n", " the tools they need." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "#### I want the same for Algebraic Combinatorics!\n", "\n", "- Federating a community in algebraic combinatorics\n", "- Free Software\n", "- Developed by users for users\n", "- Developed by a distributed community of developers\n", "- Improving an existing general purpose platform" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Sage-Combinat\n", "\n", "«Sharing Algebraic Combinatorics code since 2000»\n", "\n", "#### 2000-2008 MuPAD-Combinat\n", "\n", "- The good: going from 1 to 32 contributors\n", "- The bad: MuPAD is not free software\n", "- The hope: Sage appearing in 2005" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "#### 2008- Sage-Combinat\n", "\n", "- The good:\n", " - a solid technical foundation\n", " - a growing subcommunity \n", " within a larger community (SageMath) \n", " within larger communities (Computational math soft, python for Science, ...)\n", "- The bad: \n", " - missing some foundation => distraction: implementing categories\n", " - at some point: some crazy workflow" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "#### Observations\n", "The good:\n", "- Enough man power to develop research code\n", "- Enough funding for community building (Sage Days, ...) \n", " e.g. as part of research grants" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "The bad:\n", "- William struggling with funding\n", "- Long term technical tasks lagging behind \n", " e.g. porting to Python 2, Windows" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## The making of OpenDreamKit" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "### My personal strategy for the longest time\n", "- Focus on coding and community building!\n", "- Focus on keeping my freedom!" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "### And then ...\n", "\n", "**A question of Bruce Westbury at [FPSAC 2013](http://fpsac.org) in Paris:**\n", "
\n", " *Given unlimited funding, what would you do with it for Sage?*\n", "
" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "**Growing conviction**: at this stage SageMath really needs:\n", "- dedicated Research Software Engineers\n", "- funding for them!" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "Doable ????" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### The making of: approach\n", "\n", "#### Follow a dream\n", "\n", "- Open source, open data, open publications, **open proposal**\n", "\n", "- Bottom up:\n", " - analyze and collect the needs of our community\n", " - choose a call accordingly\n", " - find a story that binds them all" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "#### Engage the community, foster collective intelligence\n", "\n", "##### Open Proposal\n", "\n", "- Broad invitation to participate to the definition of the project\n", "- Public writing of the project" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "##### Develop and share the **vision** on the project\n", "\n", "- Who are we?\n", "- What are our aims?\n", "- Where do we start from?\n", "- What is our strategy?\n", "- How does this project relate to other projects?\n", "- Why are we the dream team for the task?" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "#### Empower the participants\n", "\n", "##### Encourage\n", "\n", "- to jointly define the vision of the project\n", "- to do what they think is right (they know better)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "##### Enable\n", "\n", "- What's the status of the proposal?\n", "- What remains to do?\n", "- How can they help?" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "##### Smile, run forward, and hope ... and be thankful" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "We started with Vincent Delecroix and Thierry Monteil and ... it grew organically\n", "\n", "[Video](https://www.youtube.com/watch?v=kM9zcfRtOqo)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## OpenDreamKit (2015-2019)\n", "\n", "
\n", " Open Digital Research Environment Toolkit
\n", " for the Advancement of Mathematics
\n", " OpenDreamKit.org\n", "
\n", "\n", "**Work Programme**: [Horizon 2020](https://ec.europa.eu/programmes/horizon2020/), [European Research Infrastructures](https://ec.europa.eu/programmes/horizon2020/en/h2020-section/european-research-infrastructures-including-e-infrastructures)\n", "\n", "**Call**: Virtual Research Environments\n", "\n", "**Budget**: 7.6 M€\n", "\n", "**Aim**: support the ecosystem of open source software for **pure maths and applications**\n", "- Software engineering: portability, interoperability, distribution, HPC, ...\n", "- Jupyter-based interactive environments\n", "\n", "**Consortium**: [15 sites, 50 participants](http://opendreamkit.org/partners), ... together with the international community!\n", "\n", "**Software**: GAP, Jupyter, Linbox, Pari, Singular, SageMath, ..." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Some concrete contributions to Sage\n", "### Engineering\n", "- Jupyter: migration & widgets\n", "- Packaging (Docker, Debian, Conda, ...), portability (Windows)\n", "- Build system / continuous integration\n", "- Modularity (Sage packages)\n", "- GAP integration\n", "- Python 3" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "$\\Longrightarrow$\n", "- For devs: SageMath and friends are better citizens in the ecosystem of computational software\n", "- For users: leverages access, sharing, publication, reproducibility, ..." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "### Research work\n", "- Using semantic for high level integration\n", "- Math databases" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Demo: integration Sage + GAP + GAP's Semigroups + libsemigroups toward modular representation theory of semigroups" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/html": [ "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import sage_annotations\n", "from mygap import mygap\n", "mygap.LoadPackage(\"Semigroups\");\n", "\n", "import sage_semigroups\n", "import sage_combinat_widgets\n", "\n", "from sage_explorer import explore\n", "from sage_explorer.sage_explorer import Settings\n", "Settings.add_property('cardinality', predicate=Groups().Finite().__contains__)\n", "Settings.add_property('conjugacy_classes', predicate=Groups().Finite().__contains__)\n", "Settings.add_property('multiplication_table', predicate=Groups().Finite().__contains__)\n", "\n", "%display unicode_art\n", "tensor.symbol = \" ⊗ \"\n", "%run style/odk.py" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "3125" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "T5 = mygap.FullTransformationSemigroup(5)\n", "T5.cardinality()" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n", "\n", "\n", "\n" ] } ], "source": [ "d_classes = T5.d_classes()\n", "for d_class in d_classes:\n", " print(d_class)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "Group([ (1,2,3,4), (1,2) ])" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "G = d_classes[1].schutzenberger_group()\n", "G" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "[ (2), (2) ]" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "[ (1), (1) ]" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "⎡ ⎛2 2 0⎞ ⎛2 0 0⎞ ⎤\n", "⎢ ⎜2 1 0⎟ ⎜0 2 2⎟ ⎥\n", "⎣ ⎝0 1 1⎠, ⎝0 0 1⎠ ⎦" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "⎡ ⎛0 1 2⎞ ⎛2 2 0⎞ ⎤\n", "⎢ ⎜2 2 1⎟ ⎜0 1 0⎟ ⎥\n", "⎣ ⎝2 2 0⎠, ⎝0 0 1⎠ ⎦" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "reps = G.irreducible_representations(GF(3))\n", "for rho in reps:\n", " display([matrix(rho(g).gap()) for g in G.group_generators()])" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "all( [ rho(g)*rho(h) == rho(g*h) for g in G for h in G ] )" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "#### Why is that impressive?\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "- Sage uses GAP for groups" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "- GAP uses MeatAxe (C library)
\n", " parallelism of MeatAxe64 " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "- Sage uses GAP's Semigroup packages for semigroups
\n", " J. Mitchell et al." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "- Semigroups uses libsemigroups (C++ library)
\n", " J. Mitchell, inspired by Semigroupe of J.-E. Pin" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "- libsemigroups uses HPC Combi
\n", " F. Hivert , with feedback from J. Mitchell" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "#### Low level interface to GAP: libgap\n", "One of ODK case studies for interfacing with other systems\n", "\n", "- libgap used to be a fragile hard to maintain fork of GAP
\n", " Volker Braun\n", " \n", "- libgap is now a standard feature of GAP
\n", " M. Horn, A. Konovalov , M. Pfeiffer , J. Demeyer , E. M. Bray , N. Thiéry , D. Pasechnik
\n", " GAP-Sage Days 2016, 2017, 2018\n", "\n", "- Made possible by GAP's build system refactoring
\n", " M. Horn, A. Konovalov , ...\n", "\n", "- A major step for sustainable packaging of GAP and Sage" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "#### libsemigroups
\n", "\n", "One of ODK case study for extracting independent low-level libraries C++\n", "\n", "- libsemigroups API design:
\n", " J. Mitchell with F. Hivert and N. Thiéry: Cernay 2017, 2018\n", "\n", "- libsemigroups Python bindings
\n", " J. Mitchell and N. Thiéry : Edinburgh, 2017, Cernay 2017, 2018\n", "\n", "- libsemibroups usable directly in Jupyter thanks to xeus-cling
\n", " S. Corlay, J. Mabile, L. Gouarin \n", "\n", "- libsemigroups packaging
\n", " J. Mitchell and N. Thiéry : Jupyter for Mathematics Workshop, Edinburgh, 2017" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "#### Sage-GAP lightweight Math-in-the-Middle interface\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "#### In action" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "Algebra of over Rational Field" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A = T5.algebra(QQ); A" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "58*B + 74*\n", " Transformation( [ 4, 5, 1, 2, 3 ] ) \n", "\n", "B + 76*1 + 72*\n", " Transformation( [ 3, 4, 5, 1, 2 ] ) \n", "\n", "B + 63*B\n", " Transformation( [ 2, 3, 4, 5, 1 ] ) Transformation( [ 5, 1, 2, 3, 4 ] )" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A.an_element() ^ 3" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "#### How it works\n", "- Enriched libgap handles with\n", "- Semantic carried over using\n", "- Alignments provided as annotations\n", "```python\n", " @semantic(mmt=\"Group\", variant=\"multiplicative\")\n", " class Groups:\n", "\n", " class ParentMethods:\n", "\n", " @semantic(gap=\"GeneratorsOfGroup\", codomain=Family[Self])\n", " @abstract_method\n", " def group_generators(self):\n", " pass\n", "```" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "#### Sage-Explorer" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "scrolled": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "ename": "NameError", "evalue": "name 'G' is not defined", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mexplore\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mG\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mNameError\u001b[0m: name 'G' is not defined" ] } ], "source": [ "explore(G)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "#### Sage-Combinat widgets" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "Sym = SymmetricFunctions(QQ['t']);\n", "s = Sym.s()" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "1 ⊗ s + s ⊗ s + s ⊗ s + s ⊗ s + s ⊗ s + s ⊗ s + \n", " ┌┬┬┐ ┌┐ ┌┬┐ ┌┐ ┌┬┬┐ ┌┐ ┌┬┐ ┌┬┐ ┌┐ ┌┬┐ ┌┬┐ \n", " ├┼┴┘ └┘ ├┼┘ └┘ └┴┴┘ ├┤ └┴┘ └┴┘ ├┤ └┴┘ └┴┘ \n", " └┘ └┘ └┘ └┘ \n", "\n", "s ⊗ s + s ⊗ s + s ⊗ 1\n", " ┌┬┐ ┌┐ ┌┬┬┐ ┌┐ ┌┬┬┐ \n", " ├┼┘ └┘ └┴┴┘ └┘ ├┼┴┘ \n", " └┘ └┘ " ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s[3,1].coproduct()" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "633faae4d7ee446e9edfc67f3b766975", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Interactive function with 1 widget\n", " p1: GridViewWidget(value=[2, 1], children=…" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "@interact\n", "def f(p1 = Partition([2,1])._widget_()):\n", " return s[p1].coproduct()" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "#### Community building\n", "- 110 events, 1800 trainees, 5000 students" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "#### Dearest to my heart\n", "\n", "- Bringing some exceptional people to the SageMath community\n", "\n", "- Bringing communities together in a collaborative spirit: GAP, ..., Oscar" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Now what?\n", "\n", "### Lessons learned\n", "\n", "- Research Software Engineers really have an impact\n", "- Sometimes it's worth shooting for the moon" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "### Limitations of EU funding\n", "\n", "- Tension between career paths and project-based funding\n", "\n", "- Running a project of the scale of ODK takes a lot of overhead\n", "\n", "- Granularity: can't always shoot for the moon\n", "\n", "- Some great admin people; but really, our EU services are not up to\n", " speed" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "### How to secure the future of our great people?\n", "\n", "They deserve it!\n", "\n", "" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Back to homework\n", "\n", "- What are the needs of our communities?\n", "- What can we do about it?\n", "- What can we do about our people?" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "### Future funding: Jupyter\n", "\n", "Jupyter is a key enabling technology for Open Science & EOSC\n", "\n", "Europe should fund core development, to support and to steer\n", "\n", "BOSSEE **Call:** European Open Science Cloud\n", "[INFRAEOSC-02-2019](http://ec.europa.eu/research/participants/portal/desktop/en/opportunities/h2020/topics/infraeosc-02-2019.html)\n", "\n", "**Scope:** Core Jupyter development, demonstrators in many areas of\n", "science\n", "\n", "**Leader:** Min-Ragan Kelley\n", "\n", "**Partners:** EGI, INSERM, QuantStack, WildTreeTech, \\...\n", "\n", "**Submitted:** January 2019; denied\n", "\n", "**Will submit again!**" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "### Future funding: FAIR mathematical data\n", "\n", "Mathematical Data have a key role to play and raise specific challenges\n", "\n", "FAIRMAT **Call:** European Open Science Cloud\n", "[INFRAEOSC-02-2019](http://ec.europa.eu/research/participants/portal/desktop/en/opportunities/h2020/topics/infraeosc-02-2019.html)\n", "\n", "**Scope:** FAIR Data in Mathematics\n", "\n", "**Leader:** Michael Kohlhase\n", "\n", "**Submitted:** January 2019; denied\n", "\n", "**Will submit again!**" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "### Future funding: COST network\n", "\n", "**Scope:** Computational mathematics / Tetrapod\n", "\n", "**Leader:** ? Key question: proper administrative support\n", "\n", "**Funding for:** community building, conferences; no RSE!\n", "\n", "How to overcome failures?\n", "\n", "- Advice most welcome!" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Take Home Messages for our funding bodies and administrations\n", "\n", "- Public bodies ought to fund basic research \n", " **Public bodies ought to fund basic scientific software\n", " development**\n", "\n", "- OpenDreamKit style collaboratively developed toolkits have the\n", " potential to massively transform how (mathematical) sciences are\n", " researched, taught, and applied \n", " **Jupyter is a key enabling technology for Open Science & EOSC \n", " Europe should fund core development, to support and steer**\n", "\n", "- Research Software Engineers are a key asset \n", " Requires funding, career paths, recognition ... and creative\n", " setups \n", " **A dozen are needed for Computational Maths and the Tetrapod**\n", "\n", "- Open Management & OpenDreamKit's spirit are powerful approaches \n", " **There is a great community here; it needs support**" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Take Home Message for would-be coordinators\n", "\n", "We need volunteers!\n", "\n", "- There are opportunities\n", "- It's an awful lot of work\n", "- It's super useful for the community\n", "- It's a once in a life time experience\n", "\n", "Go for it :-)" ] } ], "metadata": { "celltoolbar": "Diaporama", "kernelspec": { "display_name": "SageMath 9.0", "language": "sage", "name": "sagemath" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.3" }, "rise": { "auto_select": "first", "autolaunch": true, "background-image": "linear-gradient(rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0.9)), url(../../../public/images/banner.png);", "scroll": true, "start_slideshow_at": "selected", "transition": "none" }, "toc": { "base_numbering": 1, "nav_menu": {}, "number_sections": true, "sideBar": true, "skip_h1_title": true, "title_cell": "Table of Contents", "title_sidebar": "Contents", "toc_cell": false, "toc_position": {}, "toc_section_display": true, "toc_window_display": false }, "varInspector": { "cols": { "lenName": 16, "lenType": 16, "lenVar": 40 }, "kernels_config": { "0": "{", "1": " ", "10": "'", "100": "e", "101": "l", "102": "e", "103": "t", "104": "e", "105": "_", "106": "c", "107": "m", "108": "d", "109": "_", "11": ":", "110": "p", "111": "o", "112": "s", "113": "t", "114": "f", "115": "i", "116": "x", "117": ":", "118": " ", "119": "'", "12": " ", "120": "'", "121": ",", "122": " ", "123": " ", "124": " ", "125": " ", "126": " ", "127": " ", "128": " ", "129": " ", "13": "{", "130": " ", "131": " ", "132": " ", "133": " ", "134": "v", "135": "a", "136": "r", "137": "R", "138": "e", "139": "f", "14": " ", "140": "r", "141": "e", "142": "s", "143": "h", "144": "C", "145": "m", "146": "d", "147": ":", "148": " ", "149": "'", "15": " ", "150": "p", "151": "r", "152": "i", "153": "n", "154": "t", "155": "(", "156": "v", "157": "a", "158": "r", "159": "_", "16": " ", "160": "d", "161": "i", "162": "c", "163": "_", "164": "l", "165": "i", "166": "s", "167": "t", "168": "(", "169": ")", "17": " ", "170": ")", "171": "'", "172": " ", "173": " ", "174": " ", "175": " ", "176": " ", "177": " ", "178": " ", "179": " ", "18": " ", "180": "}", "181": ",", "182": " ", "183": " ", "184": "'", "185": "r", "186": "'", "187": ":", "188": " ", "189": "{", "19": " ", "190": " ", "191": " ", "192": " ", "193": " ", "194": " ", "195": " ", "196": " ", "197": " ", "198": " ", "199": " ", "2": " ", "20": " ", "200": " ", "201": " ", "202": "l", "203": "i", "204": "b", "205": "r", "206": "a", "207": "r", "208": "y", "209": ":", "21": " ", "210": " ", "211": "'", "212": "v", "213": "a", "214": "r", "215": "_", "216": "l", "217": "i", "218": "s", "219": "t", "22": " ", "220": ".", "221": "r", "222": "'", "223": ",", "224": " ", "225": " ", "226": " ", "227": " ", "228": " ", "229": " ", "23": " ", "230": " ", "231": " ", "232": " ", "233": " ", "234": " ", "235": " ", "236": "d", "237": "e", "238": "l", "239": "e", "24": " ", "240": "t", "241": "e", "242": "_", "243": "c", "244": "m", "245": "d", "246": "_", "247": "p", "248": "r", "249": "e", "25": " ", "250": "f", "251": "i", "252": "x", "253": ":", "254": " ", "255": "'", "256": "r", "257": "m", "258": "(", "259": "'", "26": "l", "260": ",", "261": " ", "262": " ", "263": " ", "264": " ", "265": " ", "266": " ", "267": " ", "268": " ", "269": " ", "27": "i", "270": " ", "271": " ", "272": " ", "273": "d", "274": "e", "275": "l", "276": "e", "277": "t", "278": "e", "279": "_", "28": "b", "280": "c", "281": "m", "282": "d", "283": "_", "284": "p", "285": "o", "286": "s", "287": "t", "288": "f", "289": "i", "29": "r", "290": "x", "291": ":", "292": " ", "293": "'", "294": ")", "295": " ", "296": "'", "297": ",", "298": " ", "299": " ", "3": "'", "30": "a", "300": " ", "301": " ", "302": " ", "303": " ", "304": " ", "305": " ", "306": " ", "307": " ", "308": " ", "309": " ", "31": "r", "310": "v", "311": "a", "312": "r", "313": "R", "314": "e", "315": "f", "316": "r", "317": "e", "318": "s", "319": "h", "32": "y", "320": "C", "321": "m", "322": "d", "323": ":", "324": " ", "325": "'", "326": "c", "327": "a", "328": "t", "329": "(", "33": ":", "330": "v", "331": "a", "332": "r", "333": "_", "334": "d", "335": "i", "336": "c", "337": "_", "338": "l", "339": "i", "34": " ", "340": "s", "341": "t", "342": "(", "343": ")", "344": ")", "345": " ", "346": "'", "347": " ", "348": " ", "349": " ", "35": "'", "350": " ", "351": " ", "352": " ", "353": " ", "354": " ", "355": "}", "356": "}", "36": "v", "37": "a", "38": "r", "39": "_", "4": "p", "40": "l", "41": "i", "42": "s", "43": "t", "44": ".", "45": "p", "46": "y", "47": "'", "48": ",", "49": " ", "5": "y", "50": " ", "51": " ", "52": " ", "53": " ", "54": " ", "55": " ", "56": " ", "57": " ", "58": " ", "59": " ", "6": "t", "60": " ", "61": "d", "62": "e", "63": "l", "64": "e", "65": "t", "66": "e", "67": "_", "68": "c", "69": "m", "7": "h", "70": "d", "71": "_", "72": "p", "73": "r", "74": "e", "75": "f", "76": "i", "77": "x", "78": ":", "79": " ", "8": "o", "80": "'", "81": "d", "82": "e", "83": "l", "84": " ", "85": "'", "86": ",", "87": " ", "88": " ", "89": " ", "9": "n", "90": " ", "91": " ", "92": " ", "93": " ", "94": " ", "95": " ", "96": " ", "97": " ", "98": " ", "99": "d" }, "types_to_exclude": [ "module", "function", "builtin_function_or_method", "instance", "_Feature" ], "window_display": false } }, "nbformat": 4, "nbformat_minor": 2 }