├── organization ├── output │ ├── nights_mdn.csv │ └── meals.csv ├── rooms.md ├── nights_and_food.csv └── process.py ├── resources ├── SageMath-thematic-tutorials │ ├── geometry.ipynb │ ├── lie.ipynb │ ├── algebraic_combinatorics.ipynb │ ├── vector_calculus.ipynb │ ├── Memory_profiling.ipynb │ ├── cython_interface.ipynb │ ├── profiling.ipynb │ └── TikzPicture-and-more.ipynb ├── SageMath-tutorials │ ├── tour.ipynb │ ├── tour_groups.ipynb │ ├── introduction.ipynb │ ├── tour_assignment.ipynb │ ├── sagetex.ipynb │ ├── tour_rings.ipynb │ ├── tour_plotting.ipynb │ ├── tour_linalg.ipynb │ └── tour_numtheory.ipynb └── SageMath-demos │ └── localization_demo.ipynb └── README.md /organization/output/nights_mdn.csv: -------------------------------------------------------------------------------- 1 | first name, last name, arrival, departure 2 | Bill,Allombert,5,7 3 | David,Ayotte,5,10 4 | Sahar,Bashan,6,10 5 | Alex,Best,5,11 6 | Ariane,Carrance,5,10 7 | Xavier,Caruso,5,11 8 | Vincent,Delecroix,5,11 9 | Nicolas,Delbovier,5,10 10 | Charles,Fougeron,5,10 11 | France,Gheeraert,5,10 12 | Sébastien,Labbé,6,11 13 | Antoine,Leudière,5,10 14 | Joseph,Musleh,5,10 15 | David,Roe,6,10 16 | Julian,Rüth,5,11 17 | Elisa,Sasso,5,10 18 | Pierre,Stas,5,10 19 | Thibaut,Verron,5,10 20 | -------------------------------------------------------------------------------- /organization/rooms.md: -------------------------------------------------------------------------------- 1 | Canard 2 | 3 | 1.0. Colvert: Xavier Caruso 4 | 1.1. Sarcelle: David Ayotte, Antoine Leudière 5 | 1.2. Tadorne: Elisa Sasso 6 | 1.3. Pilet: David Roe 7 | 1.4. Souchet: Joseph Musleh 8 | 1.5. Siffleur: France Gheeraert 9 | 1.6. Nourillon: Alex Best 10 | 1.7. Nilouin: Sébastien Labbé 11 | 1.8. Chipeau: Vincent Delecroix 12 | 1.9. Garrot: Charles Fougeron 13 | 14 | Passereaux 15 | 16 | 2.0. Martin-Pécheur: Nicolas Delbovier, Pierre Stas 17 | 2.2. Rossignol: Kai Fu, Haojie Hong 18 | 2.3. Rousserole: Ariane Carrance, Sahar Bashan 19 | 2.4. Loriot d'Europe: Germain Poullot 20 | 2.5. Bergeronnette printanière: Thibaut Verron 21 | 2.6. Panure à moustache: Bill Alombert, Julian Rüth 22 | -------------------------------------------------------------------------------- /resources/SageMath-thematic-tutorials/geometry.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "e7f0a924", 6 | "metadata": {}, 7 | "source": [ 8 | "$$\n", 9 | "\\def\\CC{\\bf C}\n", 10 | "\\def\\QQ{\\bf Q}\n", 11 | "\\def\\RR{\\bf R}\n", 12 | "\\def\\ZZ{\\bf Z}\n", 13 | "\\def\\NN{\\bf N}\n", 14 | "$$\n", 15 | "# Polyhedra\n", 16 | "\n", 17 | "Here you can find various documents that explain how to perform\n", 18 | "polyhedral computations in Sage.\n", 19 | "\n", 20 | "geometry/polyhedra\\_quicktutorial geometry/polyhedra\\_tutorial\n", 21 | "geometry/polyhedra\\_quickref geometry/tips geometry/visualization\n", 22 | "geometry/polytope\\_tikz" 23 | ] 24 | } 25 | ], 26 | "metadata": {}, 27 | "nbformat": 4, 28 | "nbformat_minor": 5 29 | } 30 | -------------------------------------------------------------------------------- /resources/SageMath-tutorials/tour.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "63044a9b", 6 | "metadata": {}, 7 | "source": [ 8 | "$$\n", 9 | "\\def\\CC{\\bf C}\n", 10 | "\\def\\QQ{\\bf Q}\n", 11 | "\\def\\RR{\\bf R}\n", 12 | "\\def\\ZZ{\\bf Z}\n", 13 | "\\def\\NN{\\bf N}\n", 14 | "$$\n", 15 | "# A Guided Tour\n", 16 | "\n", 17 | "This section is a guided tour of some of what is available in Sage. For\n", 18 | "many more examples, see \"Sage Constructions\", which is intended to\n", 19 | "answer the general question \"How do I construct ...?\". See also the\n", 20 | "\"Sage Reference Manual\", which has thousands more examples. Also note\n", 21 | "that you can interactively work through this tour in the Sage notebook\n", 22 | "by clicking the `Help` link.\n", 23 | "\n", 24 | "(If you are viewing the tutorial in the Sage notebook, press\n", 25 | "`shift-enter` to evaluate any input cell. You can even edit the input\n", 26 | "before pressing shift-enter. On some Macs you might have to press\n", 27 | "`shift-return` rather than `shift-enter`.)\n", 28 | "\n", 29 | "tour\\_assignment tour\\_help tour\\_algebra tour\\_plotting tour\\_functions\n", 30 | "tour\\_rings tour\\_linalg tour\\_polynomial tour\\_coercion tour\\_groups\n", 31 | "tour\\_numtheory tour\\_advanced" 32 | ] 33 | } 34 | ], 35 | "metadata": {}, 36 | "nbformat": 4, 37 | "nbformat_minor": 5 38 | } 39 | -------------------------------------------------------------------------------- /organization/nights_and_food.csv: -------------------------------------------------------------------------------- 1 | first name,last name,arrival,departure,where 2 | Doriann,Albertin,6 morning,9 afternoon,gite 3 | Felipe,Arbulú,5 afternoon,10 afternoon,gite 4 | Bill,Allombert,5 or 6,7,maison 5 | David,Ayotte,5 evening,10 afternoon,maison 6 | Sahar,Bashan,6 afternoon,10 afternoon,maison 7 | Paul,Bastide,6 morning,10 afternoon,gite 8 | Alex,Best,5 afternoon,11 morning,maison 9 | Pierre,Bonnet,6,10,gite 10 | Ariane,Carrance,5 afternoon,10 afternoon,maison 11 | Xavier,Caruso,5 afternoon,11 morning,maison 12 | Frédéric,Chapoton,5 afternoon,10 afternoon,gite 13 | Vincent,Delecroix,5 afternoon,11 morning,maison 14 | Nicolas,Delbovier,5 afternoon,10 afternoon,maison 15 | Charles,Fougeron,5 afternoon,10,maison 16 | Kai,Fu,6,10,gite 17 | France,Gheeraert,5 afternoon,10 morning,maison 18 | Éric,Gourgoulhon,5 afternoon,9 morning,gite 19 | Haojie,Hong,6 morning,10 evening,gite 20 | Sébastien,Labbé,6 morning,11 morning,maison 21 | Clément,Legrand-Duchesne,6 morning,10 afternoon,gite 22 | Antoine,Leudière,5 afternoon,10 afternoon,maison 23 | Marc,Mezzarobba,6 afternoon,10 afternoon,gite 24 | Joseph,Musleh,5 afternoon,10 afternoon,maison 25 | Raphaël,Pages,6 morning,10 afternoon,gite 26 | Germain,Poullot,5 evening,10 afternoon,gite 27 | David,Roe,6 morning,10 afternoon,maison 28 | Julian,Rüth,5 afternoon,11 morning,maison 29 | Elisa,Sasso,5 afternoon,10 afternoon,maison 30 | Pierre,Stas,5 afternoon,10 afternoon,maison 31 | Zoé,Varin,6 morning,10 afternoon,gite 32 | Thibaut,Verron,5 evening,10 afternoon,maison 33 | -------------------------------------------------------------------------------- /resources/SageMath-thematic-tutorials/lie.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "15840d52", 6 | "metadata": {}, 7 | "source": [ 8 | "$$\n", 9 | "\\def\\CC{\\bf C}\n", 10 | "\\def\\QQ{\\bf Q}\n", 11 | "\\def\\RR{\\bf R}\n", 12 | "\\def\\ZZ{\\bf Z}\n", 13 | "\\def\\NN{\\bf N}\n", 14 | "$$\n", 15 | "# Lie Methods and Related Combinatorics in Sage\n", 16 | "\n", 17 | "Daniel Bump (Stanford University), Ben Salisbury (Central Michigan\n", 18 | "University), and Anne Schilling (UC Davis)\n", 19 | "\n", 20 | "These notes explain how to use the mathematical software Sage for Lie\n", 21 | "group computations. Sage also contains many combinatorial algorithms. We\n", 22 | "will cover only some of these.\n", 23 | "\n", 24 | "lie/introduction lie/lie\\_basics lie/weyl\\_character\\_ring\n", 25 | "lie/branching\\_rules lie/weyl\\_groups lie/crystals lie/affine\n", 26 | "lie/integrable lie/affine\\_finite\\_crystals lie/affine\\_hw\\_crystals\n", 27 | "lie/elementary\\_crystals lie/infinity\\_crystals\n", 28 | "lie/iwahori\\_hecke\\_algebra lie/kazhdan\\_lusztig\\_polynomials\n", 29 | "lie/bibliography\n", 30 | "\n", 31 | "Preparation of this document was supported in part by NSF grants\n", 32 | "DMS-0652817, DMS-1001079, OCI-1147463, DMS--0652641, DMS--0652652,\n", 33 | "DMS--1001256, OCI–1147247 and DMS-1601026." 34 | ] 35 | } 36 | ], 37 | "metadata": {}, 38 | "nbformat": 4, 39 | "nbformat_minor": 5 40 | } 41 | -------------------------------------------------------------------------------- /resources/SageMath-thematic-tutorials/algebraic_combinatorics.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "b6b7c983", 6 | "metadata": {}, 7 | "source": [ 8 | "$$\n", 9 | "\\def\\CC{\\bf C}\n", 10 | "\\def\\QQ{\\bf Q}\n", 11 | "\\def\\RR{\\bf R}\n", 12 | "\\def\\ZZ{\\bf Z}\n", 13 | "\\def\\NN{\\bf N}\n", 14 | "$$\n", 15 | "# Algebraic Combinatorics in Sage\n", 16 | "\n", 17 | "Anne Schilling (UC Davis)\n", 18 | "\n", 19 | "These notes provide some Sage examples for Stanley's book:\n", 20 | "\n", 21 | "A free pdf version of the book without exercises can be found on\n", 22 | "[Stanley's homepage](http://www-math.mit.edu/~rstan/algcomb/index.html).\n", 23 | "\n", 24 | "Preparation of this document was supported in part by NSF grants\n", 25 | "DMS--1001256 and OCI–1147247.\n", 26 | "\n", 27 | "I would like to thank Federico Castillo (who wrote a first version of\n", 28 | "the $n$-cube section) and Nicolas M. Thiery (who wrote a slightly\n", 29 | "different French version of the Tsetlin library section) for their help.\n", 30 | "\n", 31 | "algebraic\\_combinatorics/walks algebraic\\_combinatorics/n\\_cube\n", 32 | "algebraic\\_combinatorics/tsetlin\\_library\n", 33 | "algebraic\\_combinatorics/rsk.rst\n", 34 | "\n", 35 | "Stanley2013 \n", 36 | "Richard Stanley. *Algebraic Combinatorics: walks, trees, tableaux and\n", 37 | "more*, Springer, first edition, 2013." 38 | ] 39 | } 40 | ], 41 | "metadata": {}, 42 | "nbformat": 4, 43 | "nbformat_minor": 5 44 | } 45 | -------------------------------------------------------------------------------- /resources/SageMath-thematic-tutorials/vector_calculus.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "16cf10ea", 6 | "metadata": {}, 7 | "source": [ 8 | "$$\n", 9 | "\\def\\CC{\\bf C}\n", 10 | "\\def\\QQ{\\bf Q}\n", 11 | "\\def\\RR{\\bf R}\n", 12 | "\\def\\ZZ{\\bf Z}\n", 13 | "\\def\\NN{\\bf N}\n", 14 | "$$\n", 15 | "# Tutorial: Vector Calculus in Euclidean Spaces\n", 16 | "\n", 17 | "Eric Gourgoulhon\n", 18 | "\n", 19 | "This document contains various tutorials introducing vector calculus\n", 20 | "with SageMath. The first one regards vector calculus in the\n", 21 | "3-dimensional Euclidean space $\\mathbb{E}^3$ in Cartesian coordinates,\n", 22 | "focusing on the evaluation of the standard vector operators. The second\n", 23 | "tutorial deals with the same topic but based on curvilinear (spherical\n", 24 | "and cylindrical) coordinates. The third tutorial is devoted to changes\n", 25 | "between the various coordinate systems. The fourth tutorial presents\n", 26 | "some advanced aspects, namely the treatment of $\\mathbb{E}^3$ as a\n", 27 | "Riemannian manifold. Finally, the last tutorial is devoted to\n", 28 | "2-dimensional vector calculus, using both Cartesian and polar\n", 29 | "coordinates in the Euclidean plane $\\mathbb{E}^2$; it combines various\n", 30 | "features of the other tutorials.\n", 31 | "\n", 32 | "vector\\_calculus/vector\\_calc\\_cartesian\n", 33 | "vector\\_calculus/vector\\_calc\\_curvilinear\n", 34 | "vector\\_calculus/vector\\_calc\\_change\n", 35 | "vector\\_calculus/vector\\_calc\\_advanced\n", 36 | "vector\\_calculus/vector\\_calc\\_plane" 37 | ] 38 | } 39 | ], 40 | "metadata": {}, 41 | "nbformat": 4, 42 | "nbformat_minor": 5 43 | } 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Organization of sage days 117 2 | 3 | Organization of sage days 117 in le Teich (February 2023). 4 | 5 | ## Participant check list 6 | 7 | * double check the spreadsheet [meals.csv](https://github.com/sagemath/days117/blob/master/organization/output/meals.csv). 8 | * write down your project at https://codimd.math.cnrs.fr/fXNTId-5Q06e2RVvu31g4w 9 | * create an account on https://sagemath.zulipchat.com/ 10 | * check where you stay in Maison de la nature: [organization/rooms.md](https://github.com/sagemath/days117/blob/master/organization/rooms.md) 11 | 12 | ## Schedule 13 | 14 | ### All days 15 | 16 | * 08:00-09:00 : breakfast 17 | * 12:00-13:00 : lunch 18 | * 19:30-20:30 : dinner 19 | 20 | ### Monday 6 21 | 22 | High tides : 05:54 and 18:13 23 | 24 | * 09:00-10:30 : install party + refine participant projects + make schedule for tutorials 25 | * 10:30 : participant presentations (who they are and what they want to work on) 26 | * 12:00 or 12:30 : meal 27 | * 14:00-15:30 : Introduction to SageMath + adapting your workflow (by Sébastien) 28 | * 16:00-17:00 : Basic Python and SageMath (by Vincent) 29 | * 17:30 : remote talk on "SageMath development on github" on [BigBlueButton](https://webconf.u-bordeaux.fr/b/vin-g33-6qy) (by Matthias Köppe) 30 | 31 | ### Tuesday 7 32 | 33 | High tides : 06:29 and 18:49 34 | 35 | * 09:00-10:30 Sharing code and writing Python libraries (by Sébastien) 36 | * 16:00-17:30 Combinatorics in SageMath (by Frédéric) 37 | 38 | ### Wednesday 8 39 | 40 | High tides : 07:03 and 19:56 41 | 42 | * 10:30-12:00 Write clean, efficient, documented and beautiful code (by Julian) 43 | * 14:00-15:30 Graphs in SageMath (by Vincent) 44 | 45 | ### Thursday 9 46 | 47 | High tides : 07:36 and 19:56 48 | 49 | ### Friday 10 50 | 51 | High tides : 08:08 and 20:28 52 | 53 | ### Saturday 11 54 | 55 | High tides : 08:40 and 21:01 56 | -------------------------------------------------------------------------------- /organization/output/meals.csv: -------------------------------------------------------------------------------- 1 | first name,last name,dim 5 dîner,lun 6 petit déj, lun 6 midi, lun 6 soir,mar 7 petit déj, mar 7 midi, mar 7 soir,mer 8 petit déj, mer 8 midi, mer 8 soir,jeu 8 petit déj, jeu 8 midi, jeu 8 soir,ven 9 petit déj, ven 9 midi, ven 9 soir,sam 10 petit déj 2 | Doriann,Albertin,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0 3 | Felipe,Arbulú,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0 4 | Bill,Allombert,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0 5 | David,Ayotte,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0 6 | Sahar,Bashan,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0 7 | Paul,Bastide,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0 8 | Alex,Best,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 9 | Pierre,Bonnet,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 10 | Ariane,Carrance,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0 11 | Xavier,Caruso,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 12 | Frédéric,Chapoton,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0 13 | Vincent,Delecroix,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 14 | Nicolas,Delbovier,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,0,0 15 | Charles,Fougeron,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 16 | Kai,Fu,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 17 | France,Gheeraert,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0 18 | Éric,Gourgoulhon,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0 19 | Haojie,Hong,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 20 | Sébastien,Labbé,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 21 | Clément,Legrand-Duchesne,0,0,1,1,1,1,1,0,0,1,1,1,1,1,1,0,0 22 | Antoine,Leudière,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0 23 | Marc,Mezzarobba,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0 24 | Joseph,Musleh,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0 25 | Raphaël,Pages,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0 26 | Germain,Poullot,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0 27 | David,Roe,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0 28 | Julian,Rüth,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 29 | Elisa,Sasso,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0 30 | Pierre,Stas,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0 31 | Zoé,Varin,0,0,1,1,0,0,1,1,1,1,1,1,1,1,1,0,0 32 | Thibaut,Verron,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0 33 | Elise,Goujard,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0 34 | Baptiste,Louf,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 35 | Mireille,Bousquet-Mélou,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0 36 | TOTAL,,16,18,29,31,29,31,31,28,30,30,29,30,28,27,27,9,5 37 | -------------------------------------------------------------------------------- /organization/process.py: -------------------------------------------------------------------------------- 1 | 2 | # Sun 5 evening -> 0 3 | # Mon 6 breakfast -> 1 4 | # Mon 6 lunch -> 2 5 | # Mon 6 dinner -> 3 6 | # Tue 7 -> 4, 5, 6 7 | # Wed 8 -> 7, 8, 9 8 | # Thu 9 -> 10, 11, 12 9 | # Fri 10 -> 13, 14, 15 10 | # Sat 11 breakfast -> 16 11 | 12 | import csv 13 | import warnings 14 | 15 | # additional meals 16 | guests = [ 17 | ('Elise', 'Goujard', [5]), 18 | ('Baptiste', 'Louf', [8]), 19 | ('Mireille', 'Bousquet-Mélou', [11]) 20 | ] 21 | 22 | def date_index(entry, end=False): 23 | ans = entry.split(' ') 24 | date = shift = None 25 | 26 | try: 27 | date = int(ans[0].strip()) 28 | except ValueError: 29 | warnings.warn('unknown date {!r}'.format(ans[0])) 30 | 31 | if len(ans) == 2: 32 | time = ans[1] 33 | if time == 'morning': 34 | shift = 0 35 | elif time == 'afternoon': 36 | shift = 1 37 | elif time == 'evening': 38 | shift = 2 39 | else: 40 | warnings.warn('unknown time {!r}'.format(ans[1])) 41 | 42 | if date is None: 43 | date = 11 if end else 5 44 | 45 | if shift is None: 46 | if not end: 47 | if date == 5: 48 | shift = 1 49 | else: 50 | shift = 0 51 | else: 52 | if date == 11: 53 | shift = 0 54 | else: 55 | shift = 2 56 | 57 | i = 3 * (date - 5) + shift - 1 58 | assert 0 <= i < 18, (entry, i) 59 | return i 60 | 61 | def write_meals(): 62 | with open('output/meals.csv', 'w') as meals: 63 | meals.write('first name,') 64 | meals.write('last name,') 65 | meals.write('dim 5 dîner,') 66 | meals.write('lun 6 petit déj, lun 6 midi, lun 6 soir,') 67 | meals.write('mar 7 petit déj, mar 7 midi, mar 7 soir,') 68 | meals.write('mer 8 petit déj, mer 8 midi, mer 8 soir,') 69 | meals.write('jeu 8 petit déj, jeu 8 midi, jeu 8 soir,') 70 | meals.write('ven 9 petit déj, ven 9 midi, ven 9 soir,') 71 | meals.write('sam 10 petit déj\n') 72 | 73 | csv_rows = [] 74 | with open('nights_and_food.csv') as csvfile: 75 | data = csv.DictReader(csvfile, delimiter=',') 76 | for row in data: 77 | start = date_index(row['arrival']) 78 | end = date_index(row['departure'], end=True) 79 | first_name = row['first name'] 80 | last_name = row['last name'] 81 | 82 | csv_row = [row['first name'], row['last name']] 83 | csv_row += [int(start <= x < end) for x in range(17)] 84 | 85 | if first_name == 'Nicolas' and last_name == 'Delbovier': 86 | # jeune intermittant 87 | csv_row[3::3] = [0] * 6 88 | print('nico') 89 | 90 | if first_name == 'Zoé' and last_name == 'Varin': 91 | # Zoé Varin ne sera pas la au petit dej et au repas du midi le mardi 92 | print('zoé') 93 | csv_row[2 + 4] = csv_row[2 + 5] = 0 94 | 95 | if first_name == 'Clément' and last_name == 'Legrand-Duchesne': 96 | # Clément Legrand-Duchesne ne sera pas le au petit dej et au repas du midi le mercredi. 97 | print('clément') 98 | csv_row[2 + 7] = csv_row[2 + 8] = 0 99 | 100 | csv_rows.append(csv_row) 101 | 102 | for first_name, last_name, presence in guests: 103 | csv_row = [first_name, last_name] + [0] * 17 104 | for i in presence: 105 | csv_row[2 + i] = 1 106 | csv_rows.append(csv_row) 107 | 108 | meal_numbers = [0] * 17 109 | for csv_row in csv_rows: 110 | meals.write(','.join(map(str, csv_row))) 111 | meals.write('\n') 112 | for i in range(17): 113 | meal_numbers[i] += csv_row[i + 2] 114 | 115 | meals.write('TOTAL,,') 116 | meals.write(','.join(map(str, meal_numbers))) 117 | meals.write('\n') 118 | 119 | 120 | def write_mdn_nights(): 121 | with open('nights_and_food.csv') as csvfile: 122 | data = csv.DictReader(csvfile, delimiter=',') 123 | with open('output/nights_mdn.csv', 'w') as mdn: 124 | mdn.write('first name, last name, arrival, departure\n') 125 | for row in data: 126 | first_name = row['first name'] 127 | last_name = row['last name'] 128 | arrival = row['arrival'] 129 | departure = row['departure'] 130 | where = row['where'] 131 | if where == 'maison': 132 | mdn.write('{},{},{},{}\n'.format(first_name, last_name, arrival.split()[0], departure.split()[0])) 133 | 134 | write_meals() 135 | write_mdn_nights() 136 | -------------------------------------------------------------------------------- /resources/SageMath-thematic-tutorials/Memory_profiling.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "4cc0fc5e", 6 | "metadata": {}, 7 | "source": [ 8 | "# Memory profiling" 9 | ] 10 | }, 11 | { 12 | "cell_type": "markdown", 13 | "id": "09dc1f82", 14 | "metadata": {}, 15 | "source": [ 16 | "`get_memory_usage` was disabled since Sage9.something.\n", 17 | "\n", 18 | "How can I know how much memory my code use?\n", 19 | "\n", 20 | "There are two ways, both are a bit imprecise but give a raw idea." 21 | ] 22 | }, 23 | { 24 | "cell_type": "markdown", 25 | "id": "790ac7ea", 26 | "metadata": {}, 27 | "source": [ 28 | "## Memory profiling in Shell" 29 | ] 30 | }, 31 | { 32 | "cell_type": "markdown", 33 | "id": "f04ff9ba", 34 | "metadata": {}, 35 | "source": [ 36 | "We follow this tutorial: https://pypi.org/project/memory-profiler/\n", 37 | "\n", 38 | "First, install the module:\n", 39 | "\n", 40 | "`sage -pip install memory_profiler`" 41 | ] 42 | }, 43 | { 44 | "cell_type": "markdown", 45 | "id": "39026f82", 46 | "metadata": {}, 47 | "source": [ 48 | "Now, either create a new file `example.py` with the following code:" 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": null, 54 | "id": "4413dbfc", 55 | "metadata": {}, 56 | "outputs": [], 57 | "source": [ 58 | "from memory_profiler import profile\n", 59 | "\n", 60 | "@profile\n", 61 | "def my_func():\n", 62 | " a = [1] * (10 ** 6)\n", 63 | " b = [2] * (2 * 10 ** 7)\n", 64 | " del b\n", 65 | " return a\n", 66 | " \n", 67 | "my_func()" 68 | ] 69 | }, 70 | { 71 | "cell_type": "markdown", 72 | "id": "a2274291", 73 | "metadata": {}, 74 | "source": [ 75 | "Run `python example.py` in your Shell and you'll see a line by line analysis of your code.\n", 76 | "\n", 77 | "Be carefull, if you use Sage functions, you'll need to import them, as you run python here." 78 | ] 79 | }, 80 | { 81 | "cell_type": "markdown", 82 | "id": "2de1080a", 83 | "metadata": {}, 84 | "source": [ 85 | "## Memory profiling in Jupyter Notebook" 86 | ] 87 | }, 88 | { 89 | "cell_type": "markdown", 90 | "id": "041357a9", 91 | "metadata": {}, 92 | "source": [ 93 | "We follow this tutorial: https://github.com/ianozsvald/ipython_memory_usage\n", 94 | "\n", 95 | "First, install both modules: \n", 96 | "\n", 97 | "`sage -pip install memory_profiler`\n", 98 | "\n", 99 | "`sage -pip install ipython_memory_profiler`" 100 | ] 101 | }, 102 | { 103 | "cell_type": "markdown", 104 | "id": "fef18283", 105 | "metadata": {}, 106 | "source": [ 107 | "Now, we just import the module" 108 | ] 109 | }, 110 | { 111 | "cell_type": "code", 112 | "execution_count": 1, 113 | "id": "d6886121", 114 | "metadata": {}, 115 | "outputs": [], 116 | "source": [ 117 | "import ipython_memory_usage" 118 | ] 119 | }, 120 | { 121 | "cell_type": "markdown", 122 | "id": "8c2b831b", 123 | "metadata": {}, 124 | "source": [ 125 | "And the \"magic\" commande will track the memory usage of all your cells." 126 | ] 127 | }, 128 | { 129 | "cell_type": "code", 130 | "execution_count": 2, 131 | "id": "a648b498", 132 | "metadata": {}, 133 | "outputs": [ 134 | { 135 | "data": { 136 | "text/plain": [ 137 | "'memory profile enabled'" 138 | ] 139 | }, 140 | "execution_count": 2, 141 | "metadata": {}, 142 | "output_type": "execute_result" 143 | }, 144 | { 145 | "name": "stdout", 146 | "output_type": "stream", 147 | "text": [ 148 | "In [2] used 0.1328 MiB RAM in 2.97s, peaked 0.00 MiB above current, total RAM usage 169.54 MiB\n" 149 | ] 150 | } 151 | ], 152 | "source": [ 153 | "%ipython_memory_usage_start" 154 | ] 155 | }, 156 | { 157 | "cell_type": "code", 158 | "execution_count": 7, 159 | "id": "2092ac3c", 160 | "metadata": {}, 161 | "outputs": [ 162 | { 163 | "name": "stdout", 164 | "output_type": "stream", 165 | "text": [ 166 | "In [7] used 0.0312 MiB RAM in 0.29s, peaked 7.64 MiB above current, total RAM usage 177.46 MiB\n" 167 | ] 168 | } 169 | ], 170 | "source": [ 171 | "def my_func():\n", 172 | " a = [1] * (10 ** 6)\n", 173 | " b = [2] * (2 * 10 ** 7)\n", 174 | " del b\n", 175 | " return a\n", 176 | " \n", 177 | "a = my_func()" 178 | ] 179 | }, 180 | { 181 | "cell_type": "markdown", 182 | "id": "fb5b615b", 183 | "metadata": {}, 184 | "source": [ 185 | "RAM and time are pretty accurate, but the peak is usually false.\n", 186 | "\n", 187 | "Execute the cell below several time to find a 7 MiB peak (corresponding to `a`) and a 160 MiB peak (corresponding to both `a` and `b`)." 188 | ] 189 | }, 190 | { 191 | "cell_type": "code", 192 | "execution_count": 8, 193 | "id": "b34c26e1", 194 | "metadata": { 195 | "scrolled": false 196 | }, 197 | "outputs": [ 198 | { 199 | "name": "stdout", 200 | "output_type": "stream", 201 | "text": [ 202 | "In [8] used -7.5977 MiB RAM in 0.27s, peaked 15.27 MiB above current, total RAM usage 169.86 MiB\n" 203 | ] 204 | } 205 | ], 206 | "source": [ 207 | "def my_func():\n", 208 | " a = [1] * (10 ** 6)\n", 209 | " b = [2] * (2 * 10 ** 7)\n", 210 | " del b\n", 211 | " return a\n", 212 | " \n", 213 | "a = my_func()\n", 214 | "del(a)" 215 | ] 216 | }, 217 | { 218 | "cell_type": "markdown", 219 | "id": "2924ebb3", 220 | "metadata": {}, 221 | "source": [ 222 | "You can check that a module is not imported when already there by running twice the following:" 223 | ] 224 | }, 225 | { 226 | "cell_type": "code", 227 | "execution_count": 9, 228 | "id": "97d3e40f", 229 | "metadata": {}, 230 | "outputs": [ 231 | { 232 | "name": "stdout", 233 | "output_type": "stream", 234 | "text": [ 235 | "In [9] used 6.6289 MiB RAM in 0.23s, peaked 0.00 MiB above current, total RAM usage 176.49 MiB\n" 236 | ] 237 | } 238 | ], 239 | "source": [ 240 | "import numpy" 241 | ] 242 | }, 243 | { 244 | "cell_type": "markdown", 245 | "id": "b33cac11", 246 | "metadata": {}, 247 | "source": [ 248 | "To disable the memory profiler:" 249 | ] 250 | }, 251 | { 252 | "cell_type": "code", 253 | "execution_count": 10, 254 | "id": "9a0b65ec", 255 | "metadata": {}, 256 | "outputs": [ 257 | { 258 | "data": { 259 | "text/plain": [ 260 | "'memory profile disabled'" 261 | ] 262 | }, 263 | "execution_count": 10, 264 | "metadata": {}, 265 | "output_type": "execute_result" 266 | } 267 | ], 268 | "source": [ 269 | "%ipython_memory_usage_stop" 270 | ] 271 | }, 272 | { 273 | "cell_type": "markdown", 274 | "id": "8d118bdf", 275 | "metadata": {}, 276 | "source": [ 277 | "To modify the text printed (especially if you want more digits on the output), you can find the path to the code here:" 278 | ] 279 | }, 280 | { 281 | "cell_type": "code", 282 | "execution_count": null, 283 | "id": "e6013797", 284 | "metadata": {}, 285 | "outputs": [], 286 | "source": [ 287 | "ipython_memory_usage.imu??" 288 | ] 289 | }, 290 | { 291 | "cell_type": "markdown", 292 | "id": "5fd24010", 293 | "metadata": {}, 294 | "source": [ 295 | "# On timing your computations\n", 296 | "\n", 297 | "Consider following Julian Rüth tutorial on profiling!\n", 298 | "\n", 299 | "\n", 300 | "Here is a very short anwser:\n", 301 | "\n", 302 | "In a cell, you call begin by `%%time` to measure how long the cell took to execute.\n", 303 | "Using `%%timeit` at the beginning of a cell will give a more accurate result (it will run your cell several times and make stats on it).\n", 304 | "\n", 305 | "When I want to run a code during a night, I personnaly print the current time at meaningfull instants of my code, like this:" 306 | ] 307 | }, 308 | { 309 | "cell_type": "code", 310 | "execution_count": 12, 311 | "id": "41e64647", 312 | "metadata": {}, 313 | "outputs": [ 314 | { 315 | "name": "stdout", 316 | "output_type": "stream", 317 | "text": [ 318 | "Sun Feb 12 00:23:54 2023\n", 319 | "\n", 320 | "Sun Feb 12 00:23:54 2023\n", 321 | "\n", 322 | "Sun Feb 12 00:23:54 2023\n", 323 | "\n", 324 | "Sun Feb 12 00:23:54 2023\n", 325 | "\n", 326 | "Sun Feb 12 00:23:54 2023\n", 327 | "\n", 328 | "Sun Feb 12 00:23:54 2023\n", 329 | "\n", 330 | "Sun Feb 12 00:23:54 2023\n", 331 | "\n", 332 | "Sun Feb 12 00:23:54 2023\n", 333 | "\n", 334 | "Sun Feb 12 00:23:54 2023\n", 335 | "\n", 336 | "Sun Feb 12 00:23:54 2023\n", 337 | "\n", 338 | "Sun Feb 12 00:23:54 2023\n" 339 | ] 340 | } 341 | ], 342 | "source": [ 343 | "from time import ctime, time\n", 344 | "\n", 345 | "for k in range(10):\n", 346 | " print(ctime(time()))\n", 347 | " \"Do something hard that depend on the value of k!\"\n", 348 | " \"Don't forget to print the result...\"\n", 349 | " print()\n", 350 | "print(ctime(time()))" 351 | ] 352 | } 353 | ], 354 | "metadata": { 355 | "kernelspec": { 356 | "display_name": "SageMath 9.1", 357 | "language": "sage", 358 | "name": "sagemath" 359 | }, 360 | "language_info": { 361 | "codemirror_mode": { 362 | "name": "ipython", 363 | "version": 3 364 | }, 365 | "file_extension": ".py", 366 | "mimetype": "text/x-python", 367 | "name": "python", 368 | "nbconvert_exporter": "python", 369 | "pygments_lexer": "ipython3", 370 | "version": "3.7.3" 371 | } 372 | }, 373 | "nbformat": 4, 374 | "nbformat_minor": 5 375 | } 376 | -------------------------------------------------------------------------------- /resources/SageMath-tutorials/tour_groups.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "00f86d51", 6 | "metadata": {}, 7 | "source": [ 8 | "$$\n", 9 | "\\def\\CC{\\bf C}\n", 10 | "\\def\\QQ{\\bf Q}\n", 11 | "\\def\\RR{\\bf R}\n", 12 | "\\def\\ZZ{\\bf Z}\n", 13 | "\\def\\NN{\\bf N}\n", 14 | "$$\n", 15 | "# Finite Groups, Abelian Groups\n", 16 | "\n", 17 | "Sage has some support for computing with permutation groups, finite\n", 18 | "classical groups (such as $SU(n,q)$), finite matrix groups (with your\n", 19 | "own generators), and abelian groups (even infinite ones). Much of this\n", 20 | "is implemented using the interface to GAP.\n", 21 | "\n", 22 | "For example, to create a permutation group, give a list of generators,\n", 23 | "as in the following example." 24 | ] 25 | }, 26 | { 27 | "cell_type": "code", 28 | "execution_count": null, 29 | "id": "d61f5908", 30 | "metadata": {}, 31 | "outputs": [ 32 | { 33 | "data": { 34 | "text/plain": [ 35 | "Permutation Group with generators [(3,4), (1,2,3)(4,5)]" 36 | ] 37 | }, 38 | "execution_count": 1, 39 | "metadata": {}, 40 | "output_type": "execute_result" 41 | } 42 | ], 43 | "source": [ 44 | "G = PermutationGroup(['(1,2,3)(4,5)', '(3,4)'])\n", 45 | "G" 46 | ] 47 | }, 48 | { 49 | "cell_type": "code", 50 | "execution_count": null, 51 | "id": "91b89430", 52 | "metadata": {}, 53 | "outputs": [ 54 | { 55 | "data": { 56 | "text/plain": [ 57 | "120" 58 | ] 59 | }, 60 | "execution_count": 1, 61 | "metadata": {}, 62 | "output_type": "execute_result" 63 | } 64 | ], 65 | "source": [ 66 | "G.order()" 67 | ] 68 | }, 69 | { 70 | "cell_type": "code", 71 | "execution_count": null, 72 | "id": "b6746814", 73 | "metadata": {}, 74 | "outputs": [ 75 | { 76 | "data": { 77 | "text/plain": [ 78 | "False" 79 | ] 80 | }, 81 | "execution_count": 1, 82 | "metadata": {}, 83 | "output_type": "execute_result" 84 | } 85 | ], 86 | "source": [ 87 | "G.is_abelian()" 88 | ] 89 | }, 90 | { 91 | "cell_type": "code", 92 | "execution_count": null, 93 | "id": "9c698045", 94 | "metadata": {}, 95 | "outputs": [ 96 | { 97 | "data": { 98 | "text/plain": [ 99 | "[Permutation Group with generators [(1,2,3)(4,5), (3,4)],\n", 100 | " Permutation Group with generators [(1,5)(3,4), (1,5)(2,4), (1,3,5)]]" 101 | ] 102 | }, 103 | "execution_count": 1, 104 | "metadata": {}, 105 | "output_type": "execute_result" 106 | } 107 | ], 108 | "source": [ 109 | "G.derived_series() # random-ish output" 110 | ] 111 | }, 112 | { 113 | "cell_type": "code", 114 | "execution_count": null, 115 | "id": "3e38129d", 116 | "metadata": {}, 117 | "outputs": [ 118 | { 119 | "data": { 120 | "text/plain": [ 121 | "Subgroup generated by [()] of (Permutation Group with generators [(3,4), (1,2,3)(4,5)])" 122 | ] 123 | }, 124 | "execution_count": 1, 125 | "metadata": {}, 126 | "output_type": "execute_result" 127 | } 128 | ], 129 | "source": [ 130 | "G.center()" 131 | ] 132 | }, 133 | { 134 | "cell_type": "code", 135 | "execution_count": null, 136 | "id": "0c5fb57c", 137 | "metadata": {}, 138 | "outputs": [ 139 | { 140 | "data": { 141 | "text/plain": [ 142 | "(1,5,3)(2,4)" 143 | ] 144 | }, 145 | "execution_count": 1, 146 | "metadata": {}, 147 | "output_type": "execute_result" 148 | } 149 | ], 150 | "source": [ 151 | "G.random_element() # random output" 152 | ] 153 | }, 154 | { 155 | "cell_type": "code", 156 | "execution_count": null, 157 | "id": "caf9214f", 158 | "metadata": {}, 159 | "outputs": [ 160 | { 161 | "data": { 162 | "text/plain": [ 163 | "\\langle (3,4), (1,2,3)(4,5) \\rangle" 164 | ] 165 | }, 166 | "execution_count": 1, 167 | "metadata": {}, 168 | "output_type": "execute_result" 169 | } 170 | ], 171 | "source": [ 172 | "print(latex(G))" 173 | ] 174 | }, 175 | { 176 | "cell_type": "markdown", 177 | "id": "71d278d4", 178 | "metadata": {}, 179 | "source": [ 180 | "You can also obtain the character table (in LaTeX format) in Sage:" 181 | ] 182 | }, 183 | { 184 | "cell_type": "code", 185 | "execution_count": null, 186 | "id": "86e34d85", 187 | "metadata": {}, 188 | "outputs": [ 189 | { 190 | "data": { 191 | "text/plain": [ 192 | "\\left(\\begin{array}{rrrr}\n", 193 | "1 & 1 & 1 & 1 \\\\\n", 194 | "1 & -\\zeta_{3} - 1 & \\zeta_{3} & 1 \\\\\n", 195 | "1 & \\zeta_{3} & -\\zeta_{3} - 1 & 1 \\\\\n", 196 | "3 & 0 & 0 & -1\n", 197 | "\\end{array}\\right)" 198 | ] 199 | }, 200 | "execution_count": 1, 201 | "metadata": {}, 202 | "output_type": "execute_result" 203 | } 204 | ], 205 | "source": [ 206 | "G = PermutationGroup([[(1,2),(3,4)], [(1,2,3)]])\n", 207 | "latex(G.character_table())" 208 | ] 209 | }, 210 | { 211 | "cell_type": "markdown", 212 | "id": "5b531e73", 213 | "metadata": {}, 214 | "source": [ 215 | "Sage also includes classical and matrix groups over finite fields:" 216 | ] 217 | }, 218 | { 219 | "cell_type": "code", 220 | "execution_count": null, 221 | "id": "1956c779", 222 | "metadata": {}, 223 | "outputs": [ 224 | { 225 | "data": { 226 | "text/plain": [ 227 | "(\n", 228 | "[1 0] [0 6] [0 4] [6 0] [0 6] [0 4] [0 6] [0 6] [0 6] [4 0]\n", 229 | "[0 1], [1 5], [5 5], [0 6], [1 2], [5 2], [1 0], [1 4], [1 3], [0 2],\n", 230 | "\n", 231 | "[5 0]\n", 232 | "[0 3]\n", 233 | ")" 234 | ] 235 | }, 236 | "execution_count": 1, 237 | "metadata": {}, 238 | "output_type": "execute_result" 239 | } 240 | ], 241 | "source": [ 242 | "MS = MatrixSpace(GF(7), 2)\n", 243 | "gens = [MS([[1,0],[-1,1]]),MS([[1,1],[0,1]])]\n", 244 | "G = MatrixGroup(gens)\n", 245 | "G.conjugacy_classes_representatives()" 246 | ] 247 | }, 248 | { 249 | "cell_type": "code", 250 | "execution_count": null, 251 | "id": "3c5cc113", 252 | "metadata": {}, 253 | "outputs": [ 254 | { 255 | "data": { 256 | "text/plain": [ 257 | "Symplectic Group of degree 4 over Finite Field of size 7" 258 | ] 259 | }, 260 | "execution_count": 1, 261 | "metadata": {}, 262 | "output_type": "execute_result" 263 | } 264 | ], 265 | "source": [ 266 | "G = Sp(4,GF(7))\n", 267 | "G" 268 | ] 269 | }, 270 | { 271 | "cell_type": "code", 272 | "execution_count": null, 273 | "id": "39fea0c4", 274 | "metadata": {}, 275 | "outputs": [ 276 | { 277 | "data": { 278 | "text/plain": [ 279 | "[5 5 5 1]\n", 280 | "[0 2 6 3]\n", 281 | "[5 0 1 0]\n", 282 | "[4 6 3 4]" 283 | ] 284 | }, 285 | "execution_count": 1, 286 | "metadata": {}, 287 | "output_type": "execute_result" 288 | } 289 | ], 290 | "source": [ 291 | "G.random_element() # random output" 292 | ] 293 | }, 294 | { 295 | "cell_type": "code", 296 | "execution_count": null, 297 | "id": "950ceb63", 298 | "metadata": {}, 299 | "outputs": [ 300 | { 301 | "data": { 302 | "text/plain": [ 303 | "276595200" 304 | ] 305 | }, 306 | "execution_count": 1, 307 | "metadata": {}, 308 | "output_type": "execute_result" 309 | } 310 | ], 311 | "source": [ 312 | "G.order()" 313 | ] 314 | }, 315 | { 316 | "cell_type": "markdown", 317 | "id": "98227796", 318 | "metadata": {}, 319 | "source": [ 320 | "You can also compute using abelian groups (infinite and finite):" 321 | ] 322 | }, 323 | { 324 | "cell_type": "code", 325 | "execution_count": null, 326 | "id": "920ef661", 327 | "metadata": {}, 328 | "outputs": [ 329 | { 330 | "data": { 331 | "text/plain": [ 332 | "b^2*c^3*d" 333 | ] 334 | }, 335 | "execution_count": 1, 336 | "metadata": {}, 337 | "output_type": "execute_result" 338 | } 339 | ], 340 | "source": [ 341 | "F = AbelianGroup(5, [5,5,7,8,9], names='abcde')\n", 342 | "(a, b, c, d, e) = F.gens()\n", 343 | "d * b**2 * c**3" 344 | ] 345 | }, 346 | { 347 | "cell_type": "code", 348 | "execution_count": null, 349 | "id": "0006b28e", 350 | "metadata": {}, 351 | "outputs": [ 352 | { 353 | "data": { 354 | "text/plain": [ 355 | "Multiplicative Abelian group isomorphic to C2 x C2 x C2" 356 | ] 357 | }, 358 | "execution_count": 1, 359 | "metadata": {}, 360 | "output_type": "execute_result" 361 | } 362 | ], 363 | "source": [ 364 | "F = AbelianGroup(3,[2]*3); F" 365 | ] 366 | }, 367 | { 368 | "cell_type": "code", 369 | "execution_count": null, 370 | "id": "b814eb37", 371 | "metadata": {}, 372 | "outputs": [ 373 | { 374 | "data": { 375 | "text/plain": [ 376 | "Multiplicative Abelian group isomorphic to C2 x C3" 377 | ] 378 | }, 379 | "execution_count": 1, 380 | "metadata": {}, 381 | "output_type": "execute_result" 382 | } 383 | ], 384 | "source": [ 385 | "H = AbelianGroup([2,3], names=\"xy\"); H" 386 | ] 387 | }, 388 | { 389 | "cell_type": "code", 390 | "execution_count": null, 391 | "id": "5c7a6bac", 392 | "metadata": {}, 393 | "outputs": [ 394 | { 395 | "data": { 396 | "text/plain": [ 397 | "Multiplicative Abelian group isomorphic to Z x Z x Z x Z x Z" 398 | ] 399 | }, 400 | "execution_count": 1, 401 | "metadata": {}, 402 | "output_type": "execute_result" 403 | } 404 | ], 405 | "source": [ 406 | "AbelianGroup(5)" 407 | ] 408 | }, 409 | { 410 | "cell_type": "code", 411 | "execution_count": null, 412 | "id": "eabb685d", 413 | "metadata": {}, 414 | "outputs": [ 415 | { 416 | "data": { 417 | "text/plain": [ 418 | "+Infinity" 419 | ] 420 | }, 421 | "execution_count": 1, 422 | "metadata": {}, 423 | "output_type": "execute_result" 424 | } 425 | ], 426 | "source": [ 427 | "AbelianGroup(5).order()" 428 | ] 429 | } 430 | ], 431 | "metadata": {}, 432 | "nbformat": 4, 433 | "nbformat_minor": 5 434 | } 435 | -------------------------------------------------------------------------------- /resources/SageMath-thematic-tutorials/cython_interface.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "b4e29484", 6 | "metadata": {}, 7 | "source": [ 8 | "$$\n", 9 | "\\def\\CC{\\bf C}\n", 10 | "\\def\\QQ{\\bf Q}\n", 11 | "\\def\\RR{\\bf R}\n", 12 | "\\def\\ZZ{\\bf Z}\n", 13 | "\\def\\NN{\\bf N}\n", 14 | "$$\n", 15 | "# How to call a C code (or a compiled library) from Sage ?\n", 16 | "\n", 17 | "If you have some C/C++ code that you would like to call from Sage for\n", 18 | "your own use, this document is for you.\n", 19 | "\n", 20 | "- Do you want to **contribute** to Sage by adding your interface to\n", 21 | " its code? The (more complex) instructions are [available\n", 22 | " here](http://doc.sagemath.org/html/en/developer/index.html#packaging-third-party-code).\n", 23 | "\n", 24 | "## Calling \"hello\\_world()\" from hello.c\n", 25 | "\n", 26 | "Let us suppose that you have a file named `~/my_dir/hello.c` containing:" 27 | ] 28 | }, 29 | { 30 | "cell_type": "code", 31 | "execution_count": null, 32 | "id": "a9ea99fd", 33 | "metadata": {}, 34 | "outputs": [], 35 | "source": [ 36 | "#include \n", 37 | "\n", 38 | "void hello_world(){\n", 39 | " printf(\"Hello World\\n\");\n", 40 | "}" 41 | ] 42 | }, 43 | { 44 | "cell_type": "markdown", 45 | "id": "2e16c297", 46 | "metadata": {}, 47 | "source": [ 48 | "In order to call this function from Sage, you must create a Cython file\n", 49 | "(i.e. a file whose extension is .pyx). Here, `~/my_dir/hello_sage.pyx`\n", 50 | "contains a header describing the signature of the function that you want\n", 51 | "to call:" 52 | ] 53 | }, 54 | { 55 | "cell_type": "code", 56 | "execution_count": null, 57 | "id": "5e34ef3a", 58 | "metadata": {}, 59 | "outputs": [], 60 | "source": [ 61 | "cdef extern from \"hello.c\":\n", 62 | " void hello_world()\n", 63 | "\n", 64 | "def my_bridge_function():\n", 65 | " hello_world() # This is the C function from hello.c" 66 | ] 67 | }, 68 | { 69 | "cell_type": "markdown", 70 | "id": "9188fdd6", 71 | "metadata": {}, 72 | "source": [ 73 | "You can now load this file in Sage, and call the C code though the\n", 74 | "Python function `my_bridge_function` :" 75 | ] 76 | }, 77 | { 78 | "cell_type": "code", 79 | "execution_count": null, 80 | "id": "720cc3e0", 81 | "metadata": {}, 82 | "outputs": [ 83 | { 84 | "data": { 85 | "text/plain": [ 86 | "Compiling ./hello_sage.pyx..." 87 | ] 88 | }, 89 | "execution_count": 1, 90 | "metadata": {}, 91 | "output_type": "execute_result" 92 | } 93 | ], 94 | "source": [ 95 | "%runfile hello_sage.pyx" 96 | ] 97 | }, 98 | { 99 | "cell_type": "code", 100 | "execution_count": null, 101 | "id": "b1c1275a", 102 | "metadata": {}, 103 | "outputs": [ 104 | { 105 | "data": { 106 | "text/plain": [ 107 | "Hello World" 108 | ] 109 | }, 110 | "execution_count": 1, 111 | "metadata": {}, 112 | "output_type": "execute_result" 113 | } 114 | ], 115 | "source": [ 116 | "my_bridge_function()" 117 | ] 118 | }, 119 | { 120 | "cell_type": "markdown", 121 | "id": "ce732cea", 122 | "metadata": {}, 123 | "source": [ 124 | "## Arguments and return value\n", 125 | "\n", 126 | "Calling function with more complex arguments and return values works the\n", 127 | "same way. To learn more about the Cython language, [click\n", 128 | "here](http://docs.cython.org/src/reference/language_basics.html)\n", 129 | "\n", 130 | "The following example defines a function taking and returning `int *`\n", 131 | "pointers, and involves some memory allocation. The C code defines a\n", 132 | "function whose purpose is to return the sum of two vectors as a third\n", 133 | "vector.\n", 134 | "\n", 135 | "**The C file** (`double_vector.c`)" 136 | ] 137 | }, 138 | { 139 | "cell_type": "code", 140 | "execution_count": null, 141 | "id": "e8732bcd", 142 | "metadata": {}, 143 | "outputs": [], 144 | "source": [ 145 | "#include \n", 146 | "\n", 147 | "int * sum_of_two_vectors(int n, int * vec1, int * vec2){\n", 148 | " /*\n", 149 | " INPUT : two arrays vec1,vec2 of n integers\n", 150 | " OUTPUT: an array of size n equal to vec1+vec2\n", 151 | " */\n", 152 | " int * sum = (int *) malloc(n*sizeof(int));\n", 153 | " int i;\n", 154 | "\n", 155 | " for(i=0;i malloc(n*sizeof(int))\n", 183 | " cdef int * vec2 = malloc(n*sizeof(int))\n", 184 | "\n", 185 | " # Fill the vectors\n", 186 | " for i in range(n):\n", 187 | " vec1[i] = list1[i]\n", 188 | " vec2[i] = list2[i]\n", 189 | "\n", 190 | " # Call the C function\n", 191 | " cdef int * vec3 = sum_of_two_vectors(n,vec1,vec2)\n", 192 | "\n", 193 | " # Save the answer in a Python object\n", 194 | " answer = [vec3[i] for i in range(n)]\n", 195 | "\n", 196 | " free(vec1)\n", 197 | " free(vec2)\n", 198 | " free(vec3)\n", 199 | "\n", 200 | " return answer" 201 | ] 202 | }, 203 | { 204 | "cell_type": "markdown", 205 | "id": "3d17d54b", 206 | "metadata": {}, 207 | "source": [ 208 | "**Call from Sage**:" 209 | ] 210 | }, 211 | { 212 | "cell_type": "code", 213 | "execution_count": null, 214 | "id": "9ae02fff", 215 | "metadata": {}, 216 | "outputs": [ 217 | { 218 | "data": { 219 | "text/plain": [ 220 | "Compiling ./double_vector_sage.pyx..." 221 | ] 222 | }, 223 | "execution_count": 1, 224 | "metadata": {}, 225 | "output_type": "execute_result" 226 | } 227 | ], 228 | "source": [ 229 | "%runfile double_vector_sage.pyx" 230 | ] 231 | }, 232 | { 233 | "cell_type": "code", 234 | "execution_count": null, 235 | "id": "b3912b90", 236 | "metadata": {}, 237 | "outputs": [ 238 | { 239 | "data": { 240 | "text/plain": [ 241 | "[3, 4, 5]" 242 | ] 243 | }, 244 | "execution_count": 1, 245 | "metadata": {}, 246 | "output_type": "execute_result" 247 | } 248 | ], 249 | "source": [ 250 | "sage_sum_of_vectors(3,[1,1,1],[2,3,4])" 251 | ] 252 | }, 253 | { 254 | "cell_type": "markdown", 255 | "id": "bd9bc94b", 256 | "metadata": {}, 257 | "source": [ 258 | "## Calling code from a compiled library\n", 259 | "\n", 260 | "The procedure is very similar again. For our purposes, we build a\n", 261 | "library from the file `~/my_dir/hello.c` :" 262 | ] 263 | }, 264 | { 265 | "cell_type": "code", 266 | "execution_count": null, 267 | "id": "951c25a4", 268 | "metadata": {}, 269 | "outputs": [], 270 | "source": [ 271 | "#include \n", 272 | "\n", 273 | "void hello_world(){\n", 274 | " printf(\"Hello World\\n\");\n", 275 | "}" 276 | ] 277 | }, 278 | { 279 | "cell_type": "markdown", 280 | "id": "707a7576", 281 | "metadata": {}, 282 | "source": [ 283 | "We also need a `~/my_dir/hello.h` header file:" 284 | ] 285 | }, 286 | { 287 | "cell_type": "code", 288 | "execution_count": null, 289 | "id": "aea837ea", 290 | "metadata": {}, 291 | "outputs": [], 292 | "source": [ 293 | "void hello_world();" 294 | ] 295 | }, 296 | { 297 | "cell_type": "markdown", 298 | "id": "531d93de", 299 | "metadata": {}, 300 | "source": [ 301 | "We can now **compile it** as a library:" 302 | ] 303 | }, 304 | { 305 | "cell_type": "code", 306 | "execution_count": null, 307 | "id": "babda296", 308 | "metadata": {}, 309 | "outputs": [], 310 | "source": [ 311 | "[user@localhost ~/my_dir/] gcc -c -Wall -Werror -fpic hello.c\n", 312 | "[user@localhost ~/my_dir/] gcc -shared -o libhello.so hello.o" 313 | ] 314 | }, 315 | { 316 | "cell_type": "markdown", 317 | "id": "552c425d", 318 | "metadata": {}, 319 | "source": [ 320 | "The only files that we need now are `hello.h` and `libhello.so` (you can\n", 321 | "remove the others if you like). We must now indicate the location of the\n", 322 | "`.so` and `.h` files in the header of our `~/my_dir/hello_sage.pyx`\n", 323 | "file:" 324 | ] 325 | }, 326 | { 327 | "cell_type": "code", 328 | "execution_count": null, 329 | "id": "c1c9ae99", 330 | "metadata": {}, 331 | "outputs": [], 332 | "source": [ 333 | "# distutils: libraries = /home/username/my_dir/hello\n", 334 | "\n", 335 | "cdef extern from \"hello.h\":\n", 336 | " void hello_world()\n", 337 | "\n", 338 | "def my_bridge_function():\n", 339 | " hello_world() # This is the C function from hello.c" 340 | ] 341 | }, 342 | { 343 | "cell_type": "markdown", 344 | "id": "cb8269d3", 345 | "metadata": {}, 346 | "source": [ 347 | "Note\n", 348 | "\n", 349 | "The instruction `# distutils: libraries = /home/username/my_dir/hello`\n", 350 | "indicates that the library is actually named\n", 351 | "`/home/username/my_dir/hello`. Change it according to your needs. For\n", 352 | "more information about these instructions, see\n", 353 | "\n", 354 | "\n", 355 | "We can now **load** this file in Sage and **call** the function:" 356 | ] 357 | }, 358 | { 359 | "cell_type": "code", 360 | "execution_count": null, 361 | "id": "e7e6c112", 362 | "metadata": {}, 363 | "outputs": [ 364 | { 365 | "data": { 366 | "text/plain": [ 367 | "Compiling ./hello_sage.pyx..." 368 | ] 369 | }, 370 | "execution_count": 1, 371 | "metadata": {}, 372 | "output_type": "execute_result" 373 | } 374 | ], 375 | "source": [ 376 | "%runfile hello_sage.pyx" 377 | ] 378 | }, 379 | { 380 | "cell_type": "code", 381 | "execution_count": null, 382 | "id": "e1ec9a22", 383 | "metadata": {}, 384 | "outputs": [ 385 | { 386 | "data": { 387 | "text/plain": [ 388 | "Hello World" 389 | ] 390 | }, 391 | "execution_count": 1, 392 | "metadata": {}, 393 | "output_type": "execute_result" 394 | } 395 | ], 396 | "source": [ 397 | "my_bridge_function()" 398 | ] 399 | } 400 | ], 401 | "metadata": {}, 402 | "nbformat": 4, 403 | "nbformat_minor": 5 404 | } 405 | -------------------------------------------------------------------------------- /resources/SageMath-tutorials/introduction.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "e7aa867d", 6 | "metadata": {}, 7 | "source": [ 8 | "$$\n", 9 | "\\def\\CC{\\bf C}\n", 10 | "\\def\\QQ{\\bf Q}\n", 11 | "\\def\\RR{\\bf R}\n", 12 | "\\def\\ZZ{\\bf Z}\n", 13 | "\\def\\NN{\\bf N}\n", 14 | "$$\n", 15 | "# Introduction\n", 16 | "\n", 17 | "This tutorial should take at most 3-4 hours to fully work through. You\n", 18 | "can read it in HTML or PDF versions, or from the Sage notebook click\n", 19 | "`Help`, then click `Tutorial` to interactively work through the tutorial\n", 20 | "from within Sage.\n", 21 | "\n", 22 | "Though much of Sage is implemented using Python, no Python background is\n", 23 | "needed to read this tutorial. You will want to learn Python (a very fun\n", 24 | "language!) at some point, and there are many excellent free resources\n", 25 | "for doing so: the Python Beginner's Guide [\\[PyB\\]]() lists many\n", 26 | "options. If you just want to quickly try out Sage, this tutorial is the\n", 27 | "place to start. For example:" 28 | ] 29 | }, 30 | { 31 | "cell_type": "code", 32 | "execution_count": null, 33 | "id": "0bb9d67e", 34 | "metadata": {}, 35 | "outputs": [ 36 | { 37 | "data": { 38 | "text/plain": [ 39 | "4" 40 | ] 41 | }, 42 | "execution_count": 1, 43 | "metadata": {}, 44 | "output_type": "execute_result" 45 | } 46 | ], 47 | "source": [ 48 | "2 + 2" 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": null, 54 | "id": "5ba0a7c1", 55 | "metadata": {}, 56 | "outputs": [ 57 | { 58 | "data": { 59 | "text/plain": [ 60 | "-1 * 3^2 * 223\n" 61 | ] 62 | }, 63 | "execution_count": 1, 64 | "metadata": {}, 65 | "output_type": "execute_result" 66 | } 67 | ], 68 | "source": [ 69 | "factor(-2007)" 70 | ] 71 | }, 72 | { 73 | "cell_type": "code", 74 | "execution_count": null, 75 | "id": "56f07591", 76 | "metadata": {}, 77 | "outputs": [ 78 | { 79 | "data": { 80 | "text/plain": [ 81 | "[ 0 1 2 3]\n", 82 | "[ 4 5 6 7]\n", 83 | "[ 8 9 10 11]\n", 84 | "[12 13 14 15]\n" 85 | ] 86 | }, 87 | "execution_count": 1, 88 | "metadata": {}, 89 | "output_type": "execute_result" 90 | } 91 | ], 92 | "source": [ 93 | "A = matrix(4,4, range(16)); A" 94 | ] 95 | }, 96 | { 97 | "cell_type": "code", 98 | "execution_count": null, 99 | "id": "6735d153", 100 | "metadata": {}, 101 | "outputs": [ 102 | { 103 | "data": { 104 | "text/plain": [ 105 | "x^2 * (x^2 - 30*x - 80)\n" 106 | ] 107 | }, 108 | "execution_count": 1, 109 | "metadata": {}, 110 | "output_type": "execute_result" 111 | } 112 | ], 113 | "source": [ 114 | "factor(A.charpoly())" 115 | ] 116 | }, 117 | { 118 | "cell_type": "code", 119 | "execution_count": null, 120 | "id": "8c464676", 121 | "metadata": {}, 122 | "outputs": [ 123 | { 124 | "data": { 125 | "text/plain": [ 126 | "[-3 1]\n", 127 | "[ 2 3]\n" 128 | ] 129 | }, 130 | "execution_count": 1, 131 | "metadata": {}, 132 | "output_type": "execute_result" 133 | } 134 | ], 135 | "source": [ 136 | "m = matrix(ZZ,2, range(4))\n", 137 | "m[0,0] = m[0,0] - 3\n", 138 | "m" 139 | ] 140 | }, 141 | { 142 | "cell_type": "code", 143 | "execution_count": null, 144 | "id": "315337c4", 145 | "metadata": {}, 146 | "outputs": [ 147 | { 148 | "data": { 149 | "text/plain": [ 150 | "Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5\n", 151 | "over Rational Field" 152 | ] 153 | }, 154 | "execution_count": 1, 155 | "metadata": {}, 156 | "output_type": "execute_result" 157 | } 158 | ], 159 | "source": [ 160 | "E = EllipticCurve([1,2,3,4,5]);\n", 161 | "E" 162 | ] 163 | }, 164 | { 165 | "cell_type": "code", 166 | "execution_count": null, 167 | "id": "fefac4a7", 168 | "metadata": {}, 169 | "outputs": [ 170 | { 171 | "data": { 172 | "text/plain": [ 173 | "[0, 1, 1, 0, -1, -3, 0, -1, -3, -3, -3]" 174 | ] 175 | }, 176 | "execution_count": 1, 177 | "metadata": {}, 178 | "output_type": "execute_result" 179 | } 180 | ], 181 | "source": [ 182 | "E.anlist(10)" 183 | ] 184 | }, 185 | { 186 | "cell_type": "code", 187 | "execution_count": null, 188 | "id": "452943cf", 189 | "metadata": {}, 190 | "outputs": [ 191 | { 192 | "data": { 193 | "text/plain": [ 194 | "1\n" 195 | ] 196 | }, 197 | "execution_count": 1, 198 | "metadata": {}, 199 | "output_type": "execute_result" 200 | } 201 | ], 202 | "source": [ 203 | "E.rank()" 204 | ] 205 | }, 206 | { 207 | "cell_type": "code", 208 | "execution_count": null, 209 | "id": "6a937bfb", 210 | "metadata": {}, 211 | "outputs": [ 212 | { 213 | "data": { 214 | "text/plain": [ 215 | "36/(20*sqrt(73) + 36*I*sqrt(3) + 27)" 216 | ] 217 | }, 218 | "execution_count": 1, 219 | "metadata": {}, 220 | "output_type": "execute_result" 221 | } 222 | ], 223 | "source": [ 224 | "k = 1/(sqrt(3)*I + 3/4 + sqrt(73)*5/9); k" 225 | ] 226 | }, 227 | { 228 | "cell_type": "code", 229 | "execution_count": null, 230 | "id": "996f1535", 231 | "metadata": {}, 232 | "outputs": [ 233 | { 234 | "data": { 235 | "text/plain": [ 236 | "0.165495678130644 - 0.0521492082074256*I" 237 | ] 238 | }, 239 | "execution_count": 1, 240 | "metadata": {}, 241 | "output_type": "execute_result" 242 | } 243 | ], 244 | "source": [ 245 | "N(k)" 246 | ] 247 | }, 248 | { 249 | "cell_type": "code", 250 | "execution_count": null, 251 | "id": "248a2984", 252 | "metadata": {}, 253 | "outputs": [ 254 | { 255 | "data": { 256 | "text/plain": [ 257 | "0.16549568 - 0.052149208*I" 258 | ] 259 | }, 260 | "execution_count": 1, 261 | "metadata": {}, 262 | "output_type": "execute_result" 263 | } 264 | ], 265 | "source": [ 266 | "N(k,30) # 30 \"bits\"" 267 | ] 268 | }, 269 | { 270 | "cell_type": "code", 271 | "execution_count": null, 272 | "id": "95566c61", 273 | "metadata": {}, 274 | "outputs": [ 275 | { 276 | "data": { 277 | "text/plain": [ 278 | "\\frac{36}{20 \\, \\sqrt{73} + 36 i \\, \\sqrt{3} + 27}" 279 | ] 280 | }, 281 | "execution_count": 1, 282 | "metadata": {}, 283 | "output_type": "execute_result" 284 | } 285 | ], 286 | "source": [ 287 | "latex(k)" 288 | ] 289 | }, 290 | { 291 | "cell_type": "markdown", 292 | "id": "0b3a7f56", 293 | "metadata": {}, 294 | "source": [ 295 | "## Installation\n", 296 | "\n", 297 | "If you do not have Sage installed on a computer and just want to try\n", 298 | "some commands, use it online at .\n", 299 | "\n", 300 | "See the Sage Installation Guide in the documentation section of the main\n", 301 | "Sage webpage [\\[SA\\]]() for instructions on installing Sage on your\n", 302 | "computer. Here we merely make a few comments.\n", 303 | "\n", 304 | "1. The Sage download file comes with \"batteries included\". In other\n", 305 | " words, although Sage uses Python, IPython, PARI, GAP, Singular,\n", 306 | " Maxima, NTL, GMP, and so on, you do not need to install them\n", 307 | " separately as they are included with the Sage distribution. However,\n", 308 | " to use certain Sage features, e.g., Macaulay or KASH, you must have\n", 309 | " the relevant programs installed on your computer already.\n", 310 | "\n", 311 | "2. The pre-compiled binary version of Sage (found on the Sage web site)\n", 312 | " may be easier and quicker to install than the source code version.\n", 313 | " Just unpack the file and run `sage`.\n", 314 | "\n", 315 | "3. If you'd like to use the SageTeX package (which allows you to embed\n", 316 | " the results of Sage computations into a LaTeX file), you will need\n", 317 | " to make SageTeX known to your TeX distribution. To do this, see the\n", 318 | " section \"Make SageTeX known to TeX\" in the [Sage installation\n", 319 | " guide](http://doc.sagemath.org/html/en/) ([this\n", 320 | " link](../installation/index.html) should take you to a local copy of\n", 321 | " the installation guide). It's quite easy; you just need to set an\n", 322 | " environment variable or copy a single file to a directory that TeX\n", 323 | " will search." 324 | ] 325 | }, 326 | { 327 | "cell_type": "markdown", 328 | "id": "6d08d305", 329 | "metadata": {}, 330 | "source": [ 331 | "\n", 332 | " The documentation for using SageTeX is located in\n", 333 | " `$SAGE_ROOT/venv/share/texmf/tex/latex/sagetex/`, where\n", 334 | " \"`$SAGE_ROOT`\" refers to the directory where you installed Sage\n", 335 | " --for example, `/opt/sage-9.6`.\n" 336 | ] 337 | }, 338 | { 339 | "cell_type": "markdown", 340 | "id": "2fe14103", 341 | "metadata": {}, 342 | "source": [ 343 | "## Ways to Use Sage\n", 344 | "\n", 345 | "You can use Sage in several ways.\n", 346 | "\n", 347 | "- **Notebook graphical interface:** run `sage -n jupyter`; see [the\n", 348 | " Jupyter documentation\n", 349 | " on-line](https://jupyter-notebook.readthedocs.io/en/latest/notebook.html),\n", 350 | "- **Interactive command line:** see\n", 351 | " [chapter-interactive\\_shell](chapter-interactive_shell.ipynb),\n", 352 | "- **Programs:** By writing interpreted and compiled programs in Sage\n", 353 | " (see [section-loadattach](section-loadattach.ipynb) and\n", 354 | " [section-compile](section-compile.ipynb)), and\n", 355 | "- **Scripts:** by writing stand-alone Python scripts that use the Sage\n", 356 | " library (see [section-standalone](section-standalone.ipynb)).\n", 357 | "\n", 358 | "## Longterm Goals for Sage\n", 359 | "\n", 360 | "- **Useful**: Sage's intended audience is mathematics students (from\n", 361 | " high school to graduate school), teachers, and research\n", 362 | " mathematicians. The aim is to provide software that can be used to\n", 363 | " explore and experiment with mathematical constructions in algebra,\n", 364 | " geometry, number theory, calculus, numerical computation, etc. Sage\n", 365 | " helps make it easier to interactively experiment with mathematical\n", 366 | " objects.\n", 367 | "- **Efficient:** Be fast. Sage uses highly-optimized mature software\n", 368 | " like GMP, PARI, GAP, and NTL, and so is very fast at certain\n", 369 | " operations.\n", 370 | "- **Free and open source:** The source code must be freely available\n", 371 | " and readable, so users can understand what the system is really\n", 372 | " doing and more easily extend it. Just as mathematicians gain a\n", 373 | " deeper understanding of a theorem by carefully reading or at least\n", 374 | " skimming the proof, people who do computations should be able to\n", 375 | " understand how the calculations work by reading documented source\n", 376 | " code. If you use Sage to do computations in a paper you publish, you\n", 377 | " can rest assured that your readers will always have free access to\n", 378 | " Sage and all its source code, and you are even allowed to archive\n", 379 | " and re-distribute the version of Sage you used.\n", 380 | "- **Easy to compile:** Sage should be easy to compile from source for\n", 381 | " Linux, OS X and Windows users. This provides more flexibility for\n", 382 | " users to modify the system.\n", 383 | "- **Cooperation:** Provide robust interfaces to most other computer\n", 384 | " algebra systems, including PARI, GAP, Singular, Maxima, KASH, Magma,\n", 385 | " Maple, and Mathematica. Sage is meant to unify and extend existing\n", 386 | " math software.\n", 387 | "- **Well documented:** Tutorial, programming guide, reference manual,\n", 388 | " and how-to, with numerous examples and discussion of background\n", 389 | " mathematics.\n", 390 | "- **Extensible:** Be able to define new data types or derive from\n", 391 | " built-in types, and use code written in a range of languages.\n", 392 | "- **User friendly**: It should be easy to understand what\n", 393 | " functionality is provided for a given object and to view\n", 394 | " documentation and source code. Also attain a high level of user\n", 395 | " support." 396 | ] 397 | } 398 | ], 399 | "metadata": {}, 400 | "nbformat": 4, 401 | "nbformat_minor": 5 402 | } 403 | -------------------------------------------------------------------------------- /resources/SageMath-thematic-tutorials/profiling.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "5afaf2f1", 6 | "metadata": {}, 7 | "source": [ 8 | "$$\n", 9 | "\\def\\CC{\\bf C}\n", 10 | "\\def\\QQ{\\bf Q}\n", 11 | "\\def\\RR{\\bf R}\n", 12 | "\\def\\ZZ{\\bf Z}\n", 13 | "\\def\\NN{\\bf N}\n", 14 | "$$\n", 15 | "# Profiling in Sage\n", 16 | "\n", 17 | "This page lists several methods available in Sage to measure and analyze\n", 18 | "the performances of a piece of code. For more general information on\n", 19 | "profiling, see `Profiling_(computer_programming)`.\n", 20 | "\n", 21 | "Table of contents\n", 22 | "\n", 23 | "## How long does it take? %time and %timeit\n", 24 | "\n", 25 | "The two IPython magics `%time` and `%timeit` measure the time it takes\n", 26 | "to run a command:" 27 | ] 28 | }, 29 | { 30 | "cell_type": "code", 31 | "execution_count": null, 32 | "id": "15b775b6", 33 | "metadata": {}, 34 | "outputs": [ 35 | { 36 | "data": { 37 | "text/plain": [ 38 | "CPU times: user 152 ms, sys: 0 ns, total: 152 ms\n", 39 | "Wall time: 150 ms\n" 40 | ] 41 | }, 42 | "execution_count": 1, 43 | "metadata": {}, 44 | "output_type": "execute_result" 45 | } 46 | ], 47 | "source": [ 48 | "%time p=random_prime(2**300)" 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": null, 54 | "id": "34616a5c", 55 | "metadata": {}, 56 | "outputs": [ 57 | { 58 | "data": { 59 | "text/plain": [ 60 | "10 loops, best of 3: 62.2 ms per loop" 61 | ] 62 | }, 63 | "execution_count": 1, 64 | "metadata": {}, 65 | "output_type": "execute_result" 66 | } 67 | ], 68 | "source": [ 69 | "%timeit p=random_prime(2**300)" 70 | ] 71 | }, 72 | { 73 | "cell_type": "markdown", 74 | "id": "95a14ff6", 75 | "metadata": {}, 76 | "source": [ 77 | "Note that while `%time` only runs the command once, `%timeit` tries to\n", 78 | "return a more meaningful value over several runs.\n", 79 | "\n", 80 | "For more information see `%timeit?` or [this\n", 81 | "page](https://ipython.org/ipython-doc/dev/interactive/magics.html#magic-timeit).\n", 82 | "\n", 83 | "Note that Sage provides a `timeit\n", 84 | "` function which also runs in\n", 85 | "the Sage notebook.\n", 86 | "\n", 87 | "## Python-level function calls: %prun\n", 88 | "\n", 89 | "With `%prun`, you can obtain the list of all Python functions involved\n", 90 | "in a computation, as well as the time spent on each of them:" 91 | ] 92 | }, 93 | { 94 | "cell_type": "code", 95 | "execution_count": null, 96 | "id": "620c8761", 97 | "metadata": {}, 98 | "outputs": [ 99 | { 100 | "data": { 101 | "text/plain": [ 102 | " 468 function calls in 0.439 seconds\n", 103 | "\n", 104 | "Ordered by: internal time\n", 105 | "\n", 106 | "ncalls tottime percall cumtime percall filename:lineno(function)\n", 107 | " 32 0.438 0.014 0.438 0.014 {method 'is_prime' of 'sage.rings.integer.Integer' objects}\n", 108 | " 32 0.001 0.000 0.439 0.014 arith.py:407(is_prime)\n", 109 | " 32 0.000 0.000 0.001 0.000 random.py:175(randrange)\n", 110 | " 32 0.000 0.000 0.000 0.000 random.py:244(_randbelow)\n", 111 | " ..." 112 | ] 113 | }, 114 | "execution_count": 1, 115 | "metadata": {}, 116 | "output_type": "execute_result" 117 | } 118 | ], 119 | "source": [ 120 | "%prun _=random_prime(2**500)" 121 | ] 122 | }, 123 | { 124 | "cell_type": "markdown", 125 | "id": "8a18c667", 126 | "metadata": {}, 127 | "source": [ 128 | "The most time-consuming functions should appear on the top. A\n", 129 | "description of the different columns is [available\n", 130 | "here](https://docs.python.org/3/library/profile.html#instant-user-s-manual).\n", 131 | "\n", 132 | "Note\n", 133 | "\n", 134 | "You may want to sort this list differently, e.g: use\n", 135 | "`%prun -s cumulative` for decreasing cumulative time.\n", 136 | "\n", 137 | "Alternatively, you can \"save\" this data to a `~pstats.Stats` object for\n", 138 | "further inspection:" 139 | ] 140 | }, 141 | { 142 | "cell_type": "code", 143 | "execution_count": null, 144 | "id": "1c314263", 145 | "metadata": {}, 146 | "outputs": [ 147 | { 148 | "data": { 149 | "text/plain": [ 150 | "2547" 151 | ] 152 | }, 153 | "execution_count": 1, 154 | "metadata": {}, 155 | "output_type": "execute_result" 156 | } 157 | ], 158 | "source": [ 159 | "%prun -r random_prime(2**500)\n", 160 | "stats_object = _\n", 161 | "stats_object.total_calls" 162 | ] 163 | }, 164 | { 165 | "cell_type": "markdown", 166 | "id": "f76f390c", 167 | "metadata": {}, 168 | "source": [ 169 | "For more information see `%prun?` or [this\n", 170 | "page](https://ipython.org/ipython-doc/dev/interactive/magics.html#magic-prun).\n", 171 | "\n", 172 | "**Visualize the statistics:** you can obtain a more graphical output\n", 173 | "with [RunSnake](http://www.vrplumber.com/programming/runsnakerun/) and\n", 174 | "Sage's function `runsnake` :" 175 | ] 176 | }, 177 | { 178 | "cell_type": "code", 179 | "execution_count": null, 180 | "id": "d23a4a32", 181 | "metadata": {}, 182 | "outputs": [], 183 | "source": [ 184 | "runsnake('random_prime(2**500)')" 185 | ] 186 | }, 187 | { 188 | "cell_type": "markdown", 189 | "id": "a855c35b", 190 | "metadata": {}, 191 | "source": [ 192 | "## Python-level line-by-line profiling: %lprun\n", 193 | "\n", 194 | "With [line\\_profiler](https://pypi.org/project/line-profiler) and its\n", 195 | "`%lprun` magic, you can find out which lines of one (or many) functions\n", 196 | "are the most time-consuming. The syntax is the following:" 197 | ] 198 | }, 199 | { 200 | "cell_type": "code", 201 | "execution_count": null, 202 | "id": "be25876a", 203 | "metadata": {}, 204 | "outputs": [], 205 | "source": [ 206 | "%lprun -f function1 -f function2 code_to_run" 207 | ] 208 | }, 209 | { 210 | "cell_type": "markdown", 211 | "id": "403d5bfe", 212 | "metadata": {}, 213 | "source": [ 214 | "This will display the line-by-line analysis of `function1` and\n", 215 | "`function2` when `code_to_run` is executed:" 216 | ] 217 | }, 218 | { 219 | "cell_type": "code", 220 | "execution_count": null, 221 | "id": "eaee1d54", 222 | "metadata": {}, 223 | "outputs": [ 224 | { 225 | "data": { 226 | "text/plain": [ 227 | "Line # Hits Time Per Hit % Time Line Contents\n", 228 | "==============================================================\n", 229 | "1193 def random_prime(n, proof=None, lbound=2):\n", 230 | "... ...\n", 231 | "1251 # since we don't want current_randstate to get\n", 232 | "1252 # pulled when you say \"from sage.arith.all import *\".\n", 233 | "1253 1 11 11.0 0.0 from sage.misc.randstate import current_randstate\n", 234 | "1254 1 7 7.0 0.0 from sage.structure.proof.proof import get_flag\n", 235 | "1255 1 6 6.0 0.0 proof = get_flag(proof, \"arithmetic\")\n", 236 | "1256 1 17 17.0 0.0 n = ZZ(n)\n", 237 | "..." 238 | ] 239 | }, 240 | "execution_count": 1, 241 | "metadata": {}, 242 | "output_type": "execute_result" 243 | } 244 | ], 245 | "source": [ 246 | "%lprun -f random_prime random_prime(2**500)" 247 | ] 248 | }, 249 | { 250 | "cell_type": "markdown", 251 | "id": "8b4d59f5", 252 | "metadata": {}, 253 | "source": [ 254 | "In order to install `line_profiler` you must first run the following\n", 255 | "command:" 256 | ] 257 | }, 258 | { 259 | "cell_type": "code", 260 | "execution_count": null, 261 | "id": "c5b5014d", 262 | "metadata": {}, 263 | "outputs": [], 264 | "source": [ 265 | "[user@localhost ~] sage -pip install \"line_profiler\"" 266 | ] 267 | }, 268 | { 269 | "cell_type": "markdown", 270 | "id": "9793961d", 271 | "metadata": {}, 272 | "source": [ 273 | "## C-level function calls: %crun\n", 274 | "\n", 275 | "With `%crun`, you can obtain the list of all C functions involved in a\n", 276 | "computation, as well as the time spent on each of them. You will need to\n", 277 | "have [the Google performance analysis\n", 278 | "tools](https://github.com/gperftools/gperftools) installed on your\n", 279 | "system:" 280 | ] 281 | }, 282 | { 283 | "cell_type": "code", 284 | "execution_count": null, 285 | "id": "0feb0972", 286 | "metadata": {}, 287 | "outputs": [ 288 | { 289 | "data": { 290 | "text/plain": [ 291 | "PROFILE: interrupts/evictions/bytes = 45/0/18344\n", 292 | "Total: 45 samples\n", 293 | " 0 0.0% 0.0% 35 77.8% PyEval_EvalCode\n", 294 | " 0 0.0% 0.0% 35 77.8% PyEval_EvalCodeEx\n", 295 | " 0 0.0% 0.0% 35 77.8% PyEval_EvalFrameEx\n", 296 | " 0 0.0% 0.0% 35 77.8% PyObject_Call\n", 297 | " 0 0.0% 0.0% 35 77.8% PyRun_StringFlags\n", 298 | " 0 0.0% 0.0% 35 77.8% __Pyx_PyObject_Call.constprop.73\n", 299 | "..." 300 | ] 301 | }, 302 | "execution_count": 1, 303 | "metadata": {}, 304 | "output_type": "execute_result" 305 | } 306 | ], 307 | "source": [ 308 | "%crun p=random_prime(2**500)" 309 | ] 310 | }, 311 | { 312 | "cell_type": "markdown", 313 | "id": "2b0222cf", 314 | "metadata": {}, 315 | "source": [ 316 | "For more information on `%crun`, see `sage.misc.gperftools`.\n", 317 | "\n", 318 | "## C-level line-by-line profiling: perf (Linux only)\n", 319 | "\n", 320 | "If your code is written in C or in Cython, you can find out line-by-line\n", 321 | "which are the most costly using [perf](https://perf.wiki.kernel.org)\n", 322 | "(included in the Ubuntu package `linux-tools`).\n", 323 | "\n", 324 | "The easiest way to use it is to run some (very long) computation in\n", 325 | "Sage, and to type in a console" 326 | ] 327 | }, 328 | { 329 | "cell_type": "code", 330 | "execution_count": null, 331 | "id": "436823e2", 332 | "metadata": {}, 333 | "outputs": [], 334 | "source": [ 335 | "[user@localhost ~] sudo perf top" 336 | ] 337 | }, 338 | { 339 | "cell_type": "markdown", 340 | "id": "f00934b9", 341 | "metadata": {}, 342 | "source": [ 343 | "Select the entry that interests you, and press `Enter`. The `annotate`\n", 344 | "command will show you:\n", 345 | "\n", 346 | "- the CPU instructions\n", 347 | "- the source code\n", 348 | "- the associated time" 349 | ] 350 | }, 351 | { 352 | "cell_type": "code", 353 | "execution_count": null, 354 | "id": "dfc51e94", 355 | "metadata": {}, 356 | "outputs": [], 357 | "source": [ 358 | "│ * cdef unsigned long word = (1) << (v & self.radix_mod_mask)\n", 359 | "│ * return (self.edges[place] & word) >> (v & self.radix_mod_mask) # <<<<<<<<<<<<<<\n", 360 | "│ *\n", 361 | "│ * cpdef bint has_arc(self, int u, int v) except -1:\n", 362 | "│ */\n", 363 | "│ __pyx_r = (((__pyx_v_self->edges[__pyx_v_place]) & __pyx_v_word) >> (__pyx_v_v & __pyx_v_self->radix_mod_mask));\n", 364 | "10.88 │ movslq %esi,%rsi\n", 365 | "6.52 │ and (%rdi,%rsi,8),%rax\n", 366 | "12.84 │ shr %cl,%rax" 367 | ] 368 | }, 369 | { 370 | "cell_type": "markdown", 371 | "id": "472e0cb5", 372 | "metadata": {}, 373 | "source": [ 374 | "Note\n", 375 | "\n", 376 | "- press `s` to toggle source code view\n", 377 | "- press `H` to cycle through hottest instructions\n", 378 | "- press `h` for help\n", 379 | "\n", 380 | "Alternatively, or if you have no `sudo` privileges, you can record the\n", 381 | "statistics of a specific process into a file `perf.data` from its PID.\n", 382 | "Then, visualize the result using `perf report` :" 383 | ] 384 | }, 385 | { 386 | "cell_type": "code", 387 | "execution_count": null, 388 | "id": "6a0d4e9b", 389 | "metadata": {}, 390 | "outputs": [], 391 | "source": [ 392 | "[user@localhost ~] perf record -p PID\n", 393 | "[user@localhost ~] perf report --vmlinux vmlinux" 394 | ] 395 | } 396 | ], 397 | "metadata": {}, 398 | "nbformat": 4, 399 | "nbformat_minor": 5 400 | } 401 | -------------------------------------------------------------------------------- /resources/SageMath-tutorials/tour_assignment.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "e2fc19e6", 6 | "metadata": {}, 7 | "source": [ 8 | "$$\n", 9 | "\\def\\CC{\\bf C}\n", 10 | "\\def\\QQ{\\bf Q}\n", 11 | "\\def\\RR{\\bf R}\n", 12 | "\\def\\ZZ{\\bf Z}\n", 13 | "\\def\\NN{\\bf N}\n", 14 | "$$\n", 15 | "# Assignment, Equality, and Arithmetic\n", 16 | "\n", 17 | "With some minor exceptions, Sage uses the Python programming language,\n", 18 | "so most introductory books on Python will help you to learn Sage.\n", 19 | "\n", 20 | "Sage uses `=` for assignment. It uses `==`, `<=`, `>=`, `<` and `>` for\n", 21 | "comparison:" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": null, 27 | "id": "b3e40b85", 28 | "metadata": {}, 29 | "outputs": [ 30 | { 31 | "data": { 32 | "text/plain": [ 33 | "5" 34 | ] 35 | }, 36 | "execution_count": 1, 37 | "metadata": {}, 38 | "output_type": "execute_result" 39 | } 40 | ], 41 | "source": [ 42 | "a = 5\n", 43 | "a" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": null, 49 | "id": "2a6dfee1", 50 | "metadata": {}, 51 | "outputs": [ 52 | { 53 | "data": { 54 | "text/plain": [ 55 | "True" 56 | ] 57 | }, 58 | "execution_count": 1, 59 | "metadata": {}, 60 | "output_type": "execute_result" 61 | } 62 | ], 63 | "source": [ 64 | "2 == 2" 65 | ] 66 | }, 67 | { 68 | "cell_type": "code", 69 | "execution_count": null, 70 | "id": "e08ce911", 71 | "metadata": {}, 72 | "outputs": [ 73 | { 74 | "data": { 75 | "text/plain": [ 76 | "False" 77 | ] 78 | }, 79 | "execution_count": 1, 80 | "metadata": {}, 81 | "output_type": "execute_result" 82 | } 83 | ], 84 | "source": [ 85 | "2 == 3" 86 | ] 87 | }, 88 | { 89 | "cell_type": "code", 90 | "execution_count": null, 91 | "id": "73c2c3a0", 92 | "metadata": {}, 93 | "outputs": [ 94 | { 95 | "data": { 96 | "text/plain": [ 97 | "True" 98 | ] 99 | }, 100 | "execution_count": 1, 101 | "metadata": {}, 102 | "output_type": "execute_result" 103 | } 104 | ], 105 | "source": [ 106 | "2 < 3" 107 | ] 108 | }, 109 | { 110 | "cell_type": "code", 111 | "execution_count": null, 112 | "id": "6345b221", 113 | "metadata": {}, 114 | "outputs": [ 115 | { 116 | "data": { 117 | "text/plain": [ 118 | "True" 119 | ] 120 | }, 121 | "execution_count": 1, 122 | "metadata": {}, 123 | "output_type": "execute_result" 124 | } 125 | ], 126 | "source": [ 127 | "a == 5" 128 | ] 129 | }, 130 | { 131 | "cell_type": "markdown", 132 | "id": "3ec89661", 133 | "metadata": {}, 134 | "source": [ 135 | "Sage provides all of the basic mathematical operations:" 136 | ] 137 | }, 138 | { 139 | "cell_type": "code", 140 | "execution_count": null, 141 | "id": "4ab5951a", 142 | "metadata": {}, 143 | "outputs": [ 144 | { 145 | "data": { 146 | "text/plain": [ 147 | "8" 148 | ] 149 | }, 150 | "execution_count": 1, 151 | "metadata": {}, 152 | "output_type": "execute_result" 153 | } 154 | ], 155 | "source": [ 156 | "2**3 # ** means exponent" 157 | ] 158 | }, 159 | { 160 | "cell_type": "code", 161 | "execution_count": null, 162 | "id": "3b25b162", 163 | "metadata": {}, 164 | "outputs": [ 165 | { 166 | "data": { 167 | "text/plain": [ 168 | "8" 169 | ] 170 | }, 171 | "execution_count": 1, 172 | "metadata": {}, 173 | "output_type": "execute_result" 174 | } 175 | ], 176 | "source": [ 177 | "2^3 # ^ is a synonym for ** (unlike in Python)" 178 | ] 179 | }, 180 | { 181 | "cell_type": "code", 182 | "execution_count": null, 183 | "id": "b33fa318", 184 | "metadata": {}, 185 | "outputs": [ 186 | { 187 | "data": { 188 | "text/plain": [ 189 | "1" 190 | ] 191 | }, 192 | "execution_count": 1, 193 | "metadata": {}, 194 | "output_type": "execute_result" 195 | } 196 | ], 197 | "source": [ 198 | "10 % 3 # for integer arguments, % means mod, i.e., remainder" 199 | ] 200 | }, 201 | { 202 | "cell_type": "code", 203 | "execution_count": null, 204 | "id": "4aa9702b", 205 | "metadata": {}, 206 | "outputs": [ 207 | { 208 | "data": { 209 | "text/plain": [ 210 | "5/2" 211 | ] 212 | }, 213 | "execution_count": 1, 214 | "metadata": {}, 215 | "output_type": "execute_result" 216 | } 217 | ], 218 | "source": [ 219 | "10/4" 220 | ] 221 | }, 222 | { 223 | "cell_type": "code", 224 | "execution_count": null, 225 | "id": "c127e7c1", 226 | "metadata": {}, 227 | "outputs": [ 228 | { 229 | "data": { 230 | "text/plain": [ 231 | "2" 232 | ] 233 | }, 234 | "execution_count": 1, 235 | "metadata": {}, 236 | "output_type": "execute_result" 237 | } 238 | ], 239 | "source": [ 240 | "10//4 # for integer arguments, // returns the integer quotient" 241 | ] 242 | }, 243 | { 244 | "cell_type": "code", 245 | "execution_count": null, 246 | "id": "a9ee9e1b", 247 | "metadata": {}, 248 | "outputs": [ 249 | { 250 | "data": { 251 | "text/plain": [ 252 | "True" 253 | ] 254 | }, 255 | "execution_count": 1, 256 | "metadata": {}, 257 | "output_type": "execute_result" 258 | } 259 | ], 260 | "source": [ 261 | "4 * (10 // 4) + 10 % 4 == 10" 262 | ] 263 | }, 264 | { 265 | "cell_type": "code", 266 | "execution_count": null, 267 | "id": "d1ea997f", 268 | "metadata": {}, 269 | "outputs": [ 270 | { 271 | "data": { 272 | "text/plain": [ 273 | "38" 274 | ] 275 | }, 276 | "execution_count": 1, 277 | "metadata": {}, 278 | "output_type": "execute_result" 279 | } 280 | ], 281 | "source": [ 282 | "3^2*4 + 2%5" 283 | ] 284 | }, 285 | { 286 | "cell_type": "markdown", 287 | "id": "49e2350f", 288 | "metadata": {}, 289 | "source": [ 290 | "The computation of an expression like `3^2*4 + 2%5` depends on the order\n", 291 | "in which the operations are applied; this is specified in the \"operator\n", 292 | "precedence table\" in [section-precedence](section-precedence.ipynb).\n", 293 | "\n", 294 | "Sage also provides many familiar mathematical functions; here are just a\n", 295 | "few examples:" 296 | ] 297 | }, 298 | { 299 | "cell_type": "code", 300 | "execution_count": null, 301 | "id": "2babaf9b", 302 | "metadata": {}, 303 | "outputs": [ 304 | { 305 | "data": { 306 | "text/plain": [ 307 | "1.84390889145858" 308 | ] 309 | }, 310 | "execution_count": 1, 311 | "metadata": {}, 312 | "output_type": "execute_result" 313 | } 314 | ], 315 | "source": [ 316 | "sqrt(3.4)" 317 | ] 318 | }, 319 | { 320 | "cell_type": "code", 321 | "execution_count": null, 322 | "id": "857c6352", 323 | "metadata": {}, 324 | "outputs": [ 325 | { 326 | "data": { 327 | "text/plain": [ 328 | "-0.912021158525540" 329 | ] 330 | }, 331 | "execution_count": 1, 332 | "metadata": {}, 333 | "output_type": "execute_result" 334 | } 335 | ], 336 | "source": [ 337 | "sin(5.135)" 338 | ] 339 | }, 340 | { 341 | "cell_type": "code", 342 | "execution_count": null, 343 | "id": "5d761228", 344 | "metadata": {}, 345 | "outputs": [ 346 | { 347 | "data": { 348 | "text/plain": [ 349 | "1/2*sqrt(3)" 350 | ] 351 | }, 352 | "execution_count": 1, 353 | "metadata": {}, 354 | "output_type": "execute_result" 355 | } 356 | ], 357 | "source": [ 358 | "sin(pi/3)" 359 | ] 360 | }, 361 | { 362 | "cell_type": "markdown", 363 | "id": "2711f449", 364 | "metadata": {}, 365 | "source": [ 366 | "As the last example shows, some mathematical expressions return 'exact'\n", 367 | "values, rather than numerical approximations. To get a numerical\n", 368 | "approximation, use either the function `N` or the method `n` (and both\n", 369 | "of these have a longer name, `numerical_approx`, and the function `N` is\n", 370 | "the same as `n`)). These take optional arguments `prec`, which is the\n", 371 | "requested number of bits of precision, and `digits`, which is the\n", 372 | "requested number of decimal digits of precision; the default is 53 bits\n", 373 | "of precision." 374 | ] 375 | }, 376 | { 377 | "cell_type": "code", 378 | "execution_count": null, 379 | "id": "1f64b9bd", 380 | "metadata": {}, 381 | "outputs": [ 382 | { 383 | "data": { 384 | "text/plain": [ 385 | "e^2" 386 | ] 387 | }, 388 | "execution_count": 1, 389 | "metadata": {}, 390 | "output_type": "execute_result" 391 | } 392 | ], 393 | "source": [ 394 | "exp(2)" 395 | ] 396 | }, 397 | { 398 | "cell_type": "code", 399 | "execution_count": null, 400 | "id": "12957cbe", 401 | "metadata": {}, 402 | "outputs": [ 403 | { 404 | "data": { 405 | "text/plain": [ 406 | "7.38905609893065" 407 | ] 408 | }, 409 | "execution_count": 1, 410 | "metadata": {}, 411 | "output_type": "execute_result" 412 | } 413 | ], 414 | "source": [ 415 | "n(exp(2))" 416 | ] 417 | }, 418 | { 419 | "cell_type": "code", 420 | "execution_count": null, 421 | "id": "6ce809ed", 422 | "metadata": {}, 423 | "outputs": [ 424 | { 425 | "data": { 426 | "text/plain": [ 427 | "1.77245385090552" 428 | ] 429 | }, 430 | "execution_count": 1, 431 | "metadata": {}, 432 | "output_type": "execute_result" 433 | } 434 | ], 435 | "source": [ 436 | "sqrt(pi).numerical_approx()" 437 | ] 438 | }, 439 | { 440 | "cell_type": "code", 441 | "execution_count": null, 442 | "id": "71dd6239", 443 | "metadata": {}, 444 | "outputs": [ 445 | { 446 | "data": { 447 | "text/plain": [ 448 | "-0.54402" 449 | ] 450 | }, 451 | "execution_count": 1, 452 | "metadata": {}, 453 | "output_type": "execute_result" 454 | } 455 | ], 456 | "source": [ 457 | "sin(10).n(digits=5)" 458 | ] 459 | }, 460 | { 461 | "cell_type": "code", 462 | "execution_count": null, 463 | "id": "8022da87", 464 | "metadata": {}, 465 | "outputs": [ 466 | { 467 | "data": { 468 | "text/plain": [ 469 | "-0.5440211109" 470 | ] 471 | }, 472 | "execution_count": 1, 473 | "metadata": {}, 474 | "output_type": "execute_result" 475 | } 476 | ], 477 | "source": [ 478 | "N(sin(10),digits=10)" 479 | ] 480 | }, 481 | { 482 | "cell_type": "code", 483 | "execution_count": null, 484 | "id": "c3668f54", 485 | "metadata": {}, 486 | "outputs": [ 487 | { 488 | "data": { 489 | "text/plain": [ 490 | "3.1415926535897932384626433832795028841971693993751058209749" 491 | ] 492 | }, 493 | "execution_count": 1, 494 | "metadata": {}, 495 | "output_type": "execute_result" 496 | } 497 | ], 498 | "source": [ 499 | "numerical_approx(pi, prec=200)" 500 | ] 501 | }, 502 | { 503 | "cell_type": "markdown", 504 | "id": "24f1a5ec", 505 | "metadata": {}, 506 | "source": [ 507 | "Python is dynamically typed, so the value referred to by each variable\n", 508 | "has a type associated with it, but a given variable may hold values of\n", 509 | "any Python type within a given scope:" 510 | ] 511 | }, 512 | { 513 | "cell_type": "code", 514 | "execution_count": null, 515 | "id": "6ecb1d6c", 516 | "metadata": {}, 517 | "outputs": [ 518 | { 519 | "data": { 520 | "text/plain": [ 521 | "" 522 | ] 523 | }, 524 | "execution_count": 1, 525 | "metadata": {}, 526 | "output_type": "execute_result" 527 | } 528 | ], 529 | "source": [ 530 | "a = 5 # a is an integer\n", 531 | "type(a)" 532 | ] 533 | }, 534 | { 535 | "cell_type": "code", 536 | "execution_count": null, 537 | "id": "4a97e759", 538 | "metadata": {}, 539 | "outputs": [ 540 | { 541 | "data": { 542 | "text/plain": [ 543 | "" 544 | ] 545 | }, 546 | "execution_count": 1, 547 | "metadata": {}, 548 | "output_type": "execute_result" 549 | } 550 | ], 551 | "source": [ 552 | "a = 5/3 # now a is a rational number\n", 553 | "type(a)" 554 | ] 555 | }, 556 | { 557 | "cell_type": "code", 558 | "execution_count": null, 559 | "id": "55cbdaa6", 560 | "metadata": {}, 561 | "outputs": [ 562 | { 563 | "data": { 564 | "text/plain": [ 565 | "<... 'str'>" 566 | ] 567 | }, 568 | "execution_count": 1, 569 | "metadata": {}, 570 | "output_type": "execute_result" 571 | } 572 | ], 573 | "source": [ 574 | "a = 'hello' # now a is a string\n", 575 | "type(a)" 576 | ] 577 | }, 578 | { 579 | "cell_type": "markdown", 580 | "id": "4b02ec9a", 581 | "metadata": {}, 582 | "source": [ 583 | "The C programming language, which is statically typed, is much\n", 584 | "different; a variable declared to hold an int can only hold an int in\n", 585 | "its scope." 586 | ] 587 | } 588 | ], 589 | "metadata": {}, 590 | "nbformat": 4, 591 | "nbformat_minor": 5 592 | } 593 | -------------------------------------------------------------------------------- /resources/SageMath-demos/localization_demo.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "b41d2573", 6 | "metadata": {}, 7 | "source": [ 8 | "Before running the code, please retrieve the `localization` branch from [git@github.com:xcaruso/sage].\n", 9 | "\n", 10 | "(Untested: `git fetch git@github.com:xcaruso/sage localization`)" 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": 31, 16 | "id": "e1a36670", 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "%display latex" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": 32, 26 | "id": "314aff46", 27 | "metadata": { 28 | "scrolled": true 29 | }, 30 | "outputs": [ 31 | { 32 | "data": { 33 | "text/html": [ 34 | "\\(\\displaystyle \\newcommand{\\Bold}[1]{\\mathbf{#1}}\\Bold{Q}[x, y] \\left[ \\frac{1}{x + y}, \\frac{1}{x - y}\\right]\\)" 35 | ], 36 | "text/latex": [ 37 | "$\\displaystyle \\newcommand{\\Bold}[1]{\\mathbf{#1}}\\Bold{Q}[x, y] \\left[ \\frac{1}{x + y}, \\frac{1}{x - y}\\right]$" 38 | ], 39 | "text/plain": [ 40 | "Localization of Multivariate Polynomial Ring in x, y over Rational Field at [x + y, x - y]" 41 | ] 42 | }, 43 | "execution_count": 32, 44 | "metadata": {}, 45 | "output_type": "execute_result" 46 | } 47 | ], 48 | "source": [ 49 | "P. = QQ[]\n", 50 | "L = P.localization([x+y,x-y])\n", 51 | "L" 52 | ] 53 | }, 54 | { 55 | "cell_type": "code", 56 | "execution_count": 33, 57 | "id": "4031cad6", 58 | "metadata": {}, 59 | "outputs": [ 60 | { 61 | "data": { 62 | "text/html": [ 63 | "\\(\\displaystyle \\frac{1}{\\left(x + y\\right)\\cdot \\left(x - y\\right)}\\)" 64 | ], 65 | "text/latex": [ 66 | "$\\displaystyle \\frac{1}{\\left(x + y\\right)\\cdot \\left(x - y\\right)}$" 67 | ], 68 | "text/plain": [ 69 | "(x + y)^(-1) * (x - y)^(-1)" 70 | ] 71 | }, 72 | "execution_count": 33, 73 | "metadata": {}, 74 | "output_type": "execute_result" 75 | } 76 | ], 77 | "source": [ 78 | "u,v = L.inverse_of_units()\n", 79 | "(x^2-y^2)*u^2*v^2" 80 | ] 81 | }, 82 | { 83 | "cell_type": "code", 84 | "execution_count": 34, 85 | "id": "0a6c4d3b", 86 | "metadata": {}, 87 | "outputs": [ 88 | { 89 | "data": { 90 | "text/html": [ 91 | "\\(\\displaystyle \\frac{x - y}{ x + y }\\)" 92 | ], 93 | "text/latex": [ 94 | "$\\displaystyle \\frac{x - y}{ x + y }$" 95 | ], 96 | "text/plain": [ 97 | "(x - y) * (x + y)^(-1)" 98 | ] 99 | }, 100 | "execution_count": 34, 101 | "metadata": {}, 102 | "output_type": "execute_result" 103 | } 104 | ], 105 | "source": [ 106 | "(x^2-y^2)*u^2" 107 | ] 108 | }, 109 | { 110 | "cell_type": "code", 111 | "execution_count": 35, 112 | "id": "adc41a25", 113 | "metadata": {}, 114 | "outputs": [ 115 | { 116 | "data": { 117 | "text/html": [ 118 | "\\(\\displaystyle \\mathrm{False}\\)" 119 | ], 120 | "text/latex": [ 121 | "$\\displaystyle \\mathrm{False}$" 122 | ], 123 | "text/plain": [ 124 | "False" 125 | ] 126 | }, 127 | "execution_count": 35, 128 | "metadata": {}, 129 | "output_type": "execute_result" 130 | } 131 | ], 132 | "source": [ 133 | "L(x).is_unit()" 134 | ] 135 | }, 136 | { 137 | "cell_type": "code", 138 | "execution_count": 36, 139 | "id": "a0ca6a71", 140 | "metadata": {}, 141 | "outputs": [ 142 | { 143 | "data": { 144 | "text/html": [ 145 | "\\(\\displaystyle \\mathrm{True}\\)" 146 | ], 147 | "text/latex": [ 148 | "$\\displaystyle \\mathrm{True}$" 149 | ], 150 | "text/plain": [ 151 | "True" 152 | ] 153 | }, 154 | "execution_count": 36, 155 | "metadata": {}, 156 | "output_type": "execute_result" 157 | } 158 | ], 159 | "source": [ 160 | "L(x+y).is_unit()" 161 | ] 162 | }, 163 | { 164 | "cell_type": "code", 165 | "execution_count": 37, 166 | "id": "b025c223", 167 | "metadata": {}, 168 | "outputs": [ 169 | { 170 | "data": { 171 | "text/html": [ 172 | "\\(\\displaystyle \\newcommand{\\ZZ}{\\Bold{Z}}\\newcommand{\\Bold}[1]{\\mathbf{#1}}\\ZZ/12\\ZZ \\left[ \\frac{1}{2}\\right]\\)" 173 | ], 174 | "text/latex": [ 175 | "$\\displaystyle \\newcommand{\\ZZ}{\\Bold{Z}}\\newcommand{\\Bold}[1]{\\mathbf{#1}}\\ZZ/12\\ZZ \\left[ \\frac{1}{2}\\right]$" 176 | ], 177 | "text/plain": [ 178 | "Localization of Ring of integers modulo 12 at [2]" 179 | ] 180 | }, 181 | "execution_count": 37, 182 | "metadata": {}, 183 | "output_type": "execute_result" 184 | } 185 | ], 186 | "source": [ 187 | "L = Integers(12).localization([2])\n", 188 | "L" 189 | ] 190 | }, 191 | { 192 | "cell_type": "code", 193 | "execution_count": 38, 194 | "id": "493973df", 195 | "metadata": {}, 196 | "outputs": [ 197 | { 198 | "data": { 199 | "text/html": [ 200 | "\\(\\displaystyle \\left(\\mathrm{True}, 2\\right)\\)" 201 | ], 202 | "text/latex": [ 203 | "$\\displaystyle \\left(\\mathrm{True}, 2\\right)$" 204 | ], 205 | "text/plain": [ 206 | "(True, 2)" 207 | ] 208 | }, 209 | "execution_count": 38, 210 | "metadata": {}, 211 | "output_type": "execute_result" 212 | } 213 | ], 214 | "source": [ 215 | "L(2).is_unit(),L(2)" 216 | ] 217 | }, 218 | { 219 | "cell_type": "code", 220 | "execution_count": 39, 221 | "id": "b865e46a", 222 | "metadata": {}, 223 | "outputs": [ 224 | { 225 | "data": { 226 | "text/html": [ 227 | "\\(\\displaystyle \\mathrm{True}\\)" 228 | ], 229 | "text/latex": [ 230 | "$\\displaystyle \\mathrm{True}$" 231 | ], 232 | "text/plain": [ 233 | "True" 234 | ] 235 | }, 236 | "execution_count": 39, 237 | "metadata": {}, 238 | "output_type": "execute_result" 239 | } 240 | ], 241 | "source": [ 242 | "L(4).is_unit()" 243 | ] 244 | }, 245 | { 246 | "cell_type": "code", 247 | "execution_count": 40, 248 | "id": "c9c752f8", 249 | "metadata": {}, 250 | "outputs": [ 251 | { 252 | "data": { 253 | "text/html": [ 254 | "\\(\\displaystyle \\frac{3}{2^{2}}\\)" 255 | ], 256 | "text/latex": [ 257 | "$\\displaystyle \\frac{3}{2^{2}}$" 258 | ], 259 | "text/plain": [ 260 | "3 * 2^(-2)" 261 | ] 262 | }, 263 | "execution_count": 40, 264 | "metadata": {}, 265 | "output_type": "execute_result" 266 | } 267 | ], 268 | "source": [ 269 | "L(3,[2])" 270 | ] 271 | }, 272 | { 273 | "cell_type": "code", 274 | "execution_count": 41, 275 | "id": "3169349d", 276 | "metadata": {}, 277 | "outputs": [ 278 | { 279 | "data": { 280 | "text/html": [ 281 | "\\(\\displaystyle \\mathrm{False}\\)" 282 | ], 283 | "text/latex": [ 284 | "$\\displaystyle \\mathrm{False}$" 285 | ], 286 | "text/plain": [ 287 | "False" 288 | ] 289 | }, 290 | "execution_count": 41, 291 | "metadata": {}, 292 | "output_type": "execute_result" 293 | } 294 | ], 295 | "source": [ 296 | "L(3).is_unit()" 297 | ] 298 | }, 299 | { 300 | "cell_type": "code", 301 | "execution_count": 43, 302 | "id": "0d2cad7b", 303 | "metadata": {}, 304 | "outputs": [], 305 | "source": [ 306 | "L = Integers(12).localization([2,3])" 307 | ] 308 | }, 309 | { 310 | "cell_type": "code", 311 | "execution_count": 44, 312 | "id": "1aa6ce30", 313 | "metadata": {}, 314 | "outputs": [ 315 | { 316 | "data": { 317 | "text/html": [ 318 | "\\(\\displaystyle \\newcommand{\\ZZ}{\\Bold{Z}}\\newcommand{\\Bold}[1]{\\mathbf{#1}}\\ZZ/12\\ZZ \\left[ \\frac{1}{2}, \\frac{1}{3}\\right]\\)" 319 | ], 320 | "text/latex": [ 321 | "$\\displaystyle \\newcommand{\\ZZ}{\\Bold{Z}}\\newcommand{\\Bold}[1]{\\mathbf{#1}}\\ZZ/12\\ZZ \\left[ \\frac{1}{2}, \\frac{1}{3}\\right]$" 322 | ], 323 | "text/plain": [ 324 | "Localization of Ring of integers modulo 12 at [2, 3]" 325 | ] 326 | }, 327 | "execution_count": 44, 328 | "metadata": {}, 329 | "output_type": "execute_result" 330 | } 331 | ], 332 | "source": [ 333 | "L" 334 | ] 335 | }, 336 | { 337 | "cell_type": "code", 338 | "execution_count": 45, 339 | "id": "367da04f", 340 | "metadata": {}, 341 | "outputs": [ 342 | { 343 | "data": { 344 | "text/html": [ 345 | "\\(\\displaystyle \\mathrm{True}\\)" 346 | ], 347 | "text/latex": [ 348 | "$\\displaystyle \\mathrm{True}$" 349 | ], 350 | "text/plain": [ 351 | "True" 352 | ] 353 | }, 354 | "execution_count": 45, 355 | "metadata": {}, 356 | "output_type": "execute_result" 357 | } 358 | ], 359 | "source": [ 360 | "L(0).is_unit()" 361 | ] 362 | }, 363 | { 364 | "cell_type": "code", 365 | "execution_count": 46, 366 | "id": "6bd606ef", 367 | "metadata": {}, 368 | "outputs": [ 369 | { 370 | "data": { 371 | "text/html": [ 372 | "\\(\\displaystyle \\mathrm{True}\\)" 373 | ], 374 | "text/latex": [ 375 | "$\\displaystyle \\mathrm{True}$" 376 | ], 377 | "text/plain": [ 378 | "True" 379 | ] 380 | }, 381 | "execution_count": 46, 382 | "metadata": {}, 383 | "output_type": "execute_result" 384 | } 385 | ], 386 | "source": [ 387 | "L.is_zero()" 388 | ] 389 | }, 390 | { 391 | "cell_type": "code", 392 | "execution_count": 47, 393 | "id": "fdf19d7d", 394 | "metadata": {}, 395 | "outputs": [ 396 | { 397 | "data": { 398 | "text/html": [ 399 | "\\(\\displaystyle \\newcommand{\\Bold}[1]{\\mathbf{#1}}\\Bold{Q}[x, y]/\\left(x y\\right)\\Bold{Q}[x, y] \\left[ \\frac{1}{x}\\right]\\)" 400 | ], 401 | "text/latex": [ 402 | "$\\displaystyle \\newcommand{\\Bold}[1]{\\mathbf{#1}}\\Bold{Q}[x, y]/\\left(x y\\right)\\Bold{Q}[x, y] \\left[ \\frac{1}{x}\\right]$" 403 | ], 404 | "text/plain": [ 405 | "Localization of Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x*y) at [x]" 406 | ] 407 | }, 408 | "execution_count": 47, 409 | "metadata": {}, 410 | "output_type": "execute_result" 411 | } 412 | ], 413 | "source": [ 414 | "P2. = P.quotient([x*y])\n", 415 | "P3 = P2.localization([x])\n", 416 | "P3" 417 | ] 418 | }, 419 | { 420 | "cell_type": "code", 421 | "execution_count": 48, 422 | "id": "34d88ad7", 423 | "metadata": {}, 424 | "outputs": [ 425 | { 426 | "data": { 427 | "text/html": [ 428 | "\\(\\displaystyle \\mathrm{True}\\)" 429 | ], 430 | "text/latex": [ 431 | "$\\displaystyle \\mathrm{True}$" 432 | ], 433 | "text/plain": [ 434 | "True" 435 | ] 436 | }, 437 | "execution_count": 48, 438 | "metadata": {}, 439 | "output_type": "execute_result" 440 | } 441 | ], 442 | "source": [ 443 | "P3(y) == P3(0)" 444 | ] 445 | }, 446 | { 447 | "cell_type": "code", 448 | "execution_count": 49, 449 | "id": "ccb7ef56", 450 | "metadata": {}, 451 | "outputs": [ 452 | { 453 | "data": { 454 | "text/html": [ 455 | "\\(\\displaystyle \\mathrm{False}\\)" 456 | ], 457 | "text/latex": [ 458 | "$\\displaystyle \\mathrm{False}$" 459 | ], 460 | "text/plain": [ 461 | "False" 462 | ] 463 | }, 464 | "execution_count": 49, 465 | "metadata": {}, 466 | "output_type": "execute_result" 467 | } 468 | ], 469 | "source": [ 470 | "P3.is_zero()" 471 | ] 472 | }, 473 | { 474 | "cell_type": "code", 475 | "execution_count": 50, 476 | "id": "f3ab31d8", 477 | "metadata": {}, 478 | "outputs": [], 479 | "source": [ 480 | "P4 = P3.quotient([x])" 481 | ] 482 | }, 483 | { 484 | "cell_type": "code", 485 | "execution_count": 52, 486 | "id": "7fb78c42", 487 | "metadata": {}, 488 | "outputs": [ 489 | { 490 | "data": { 491 | "text/plain": [ 492 | "Quotient of Localization of Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x*y) at [x] by the ideal (x)" 493 | ] 494 | }, 495 | "execution_count": 52, 496 | "metadata": {}, 497 | "output_type": "execute_result" 498 | } 499 | ], 500 | "source": [ 501 | "%display plain\n", 502 | "P4" 503 | ] 504 | }, 505 | { 506 | "cell_type": "code", 507 | "execution_count": 53, 508 | "id": "a01f268f", 509 | "metadata": {}, 510 | "outputs": [ 511 | { 512 | "data": { 513 | "text/plain": [ 514 | "True" 515 | ] 516 | }, 517 | "execution_count": 53, 518 | "metadata": {}, 519 | "output_type": "execute_result" 520 | } 521 | ], 522 | "source": [ 523 | "P4.is_zero()" 524 | ] 525 | }, 526 | { 527 | "cell_type": "code", 528 | "execution_count": 54, 529 | "id": "a5df5a3f", 530 | "metadata": {}, 531 | "outputs": [ 532 | { 533 | "data": { 534 | "text/plain": [ 535 | "True" 536 | ] 537 | }, 538 | "execution_count": 54, 539 | "metadata": {}, 540 | "output_type": "execute_result" 541 | } 542 | ], 543 | "source": [ 544 | "1 in P3.ideal([x])" 545 | ] 546 | }, 547 | { 548 | "cell_type": "code", 549 | "execution_count": null, 550 | "id": "ed2ad4a0", 551 | "metadata": {}, 552 | "outputs": [], 553 | "source": [ 554 | "1 in P3.ideal([y])" 555 | ] 556 | }, 557 | { 558 | "cell_type": "markdown", 559 | "id": "953fb270", 560 | "metadata": {}, 561 | "source": [] 562 | } 563 | ], 564 | "metadata": { 565 | "kernelspec": { 566 | "display_name": "SageMath 9.8.rc1", 567 | "language": "sage", 568 | "name": "sagemath" 569 | }, 570 | "language_info": { 571 | "codemirror_mode": { 572 | "name": "ipython", 573 | "version": 3 574 | }, 575 | "file_extension": ".py", 576 | "mimetype": "text/x-python", 577 | "name": "python", 578 | "nbconvert_exporter": "python", 579 | "pygments_lexer": "ipython3", 580 | "version": "3.11.1" 581 | } 582 | }, 583 | "nbformat": 4, 584 | "nbformat_minor": 5 585 | } 586 | -------------------------------------------------------------------------------- /resources/SageMath-tutorials/sagetex.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "5e92148e", 6 | "metadata": {}, 7 | "source": [ 8 | "$$\n", 9 | "\\def\\CC{\\bf C}\n", 10 | "\\def\\QQ{\\bf Q}\n", 11 | "\\def\\RR{\\bf R}\n", 12 | "\\def\\ZZ{\\bf Z}\n", 13 | "\\def\\NN{\\bf N}\n", 14 | "$$\n", 15 | "# Using SageTeX\n", 16 | "\n", 17 | "The SageTeX package allows you to embed the results of Sage computations\n", 18 | "into a LaTeX document. To use it, you will need to \"install\" it first\n", 19 | "(see [sec-sagetex\\_install](sec-sagetex_install.ipynb)).\n", 20 | "\n", 21 | "## An example\n", 22 | "\n", 23 | "Here is a very brief example of using SageTeX. The full documentation\n", 24 | "can be found in `SAGE_ROOT/venv/share/doc/sagetex`, where `SAGE_ROOT` is\n", 25 | "the directory where your Sage installation is located. That directory\n", 26 | "contains the documentation and an example file. See\n", 27 | "`SAGE_ROOT/venv/share/texmf/tex/latex/sagetex` for some possibly useful\n", 28 | "Python scripts.\n", 29 | "\n", 30 | "To see how SageTeX works, follow the directions for installing SageTeX\n", 31 | "(in [sec-sagetex\\_install](sec-sagetex_install.ipynb)) and copy the\n", 32 | "following text into a file named, say, `st_example.tex` :\n", 33 | "\n", 34 | "Warning\n", 35 | "\n", 36 | "The text below will have several errors about unknown control sequences\n", 37 | "if you are viewing this in the \"live\" help. Use the static version to\n", 38 | "see the correct text." 39 | ] 40 | }, 41 | { 42 | "cell_type": "code", 43 | "execution_count": null, 44 | "id": "4da6b090", 45 | "metadata": {}, 46 | "outputs": [], 47 | "source": [ 48 | "\\documentclass{article}\n", 49 | "\\usepackage{sagetex}\n", 50 | "\n", 51 | "\\begin{document}\n", 52 | "\n", 53 | "Using Sage\\TeX, one can use Sage to compute things and put them into\n", 54 | "your \\LaTeX{} document. For example, there are\n", 55 | "$\\sage{number_of_partitions(1269)}$ integer partitions of $1269$.\n", 56 | "You don't need to compute the number yourself, or even cut and paste\n", 57 | "it from somewhere.\n", 58 | "\n", 59 | "Here's some Sage code:\n", 60 | "\n", 61 | "\\begin{sageblock}\n", 62 | " f(x) = exp(x) * sin(2*x)\n", 63 | "\\end{sageblock}\n", 64 | "\n", 65 | "The second derivative of $f$ is\n", 66 | "\n", 67 | "\\[\n", 68 | " \\frac{\\mathrm{d}^{2}}{\\mathrm{d}x^{2}} \\sage{f(x)} =\n", 69 | " \\sage{diff(f, x, 2)(x)}.\n", 70 | "\\]\n", 71 | "\n", 72 | "Here's a plot of $f$ from $-1$ to $1$:\n", 73 | "\n", 74 | "\\sageplot{plot(f, -1, 1)}\n", 75 | "\n", 76 | "\\end{document}" 77 | ] 78 | }, 79 | { 80 | "cell_type": "markdown", 81 | "id": "5ae872d1", 82 | "metadata": {}, 83 | "source": [ 84 | "Run LaTeX on `st_example.tex` as usual. Note that LaTeX will have some\n", 85 | "complaints, which will include:" 86 | ] 87 | }, 88 | { 89 | "cell_type": "code", 90 | "execution_count": null, 91 | "id": "e07de51a", 92 | "metadata": {}, 93 | "outputs": [], 94 | "source": [ 95 | "Package sagetex Warning: Graphics file\n", 96 | "sage-plots-for-st_example.tex/plot-0.eps on page 1 does not exist. Plot\n", 97 | "command is on input line 25.\n", 98 | "\n", 99 | "Package sagetex Warning: There were undefined Sage formulas and/or\n", 100 | "plots. Run Sage on st_example.sagetex.sage, and then run LaTeX on\n", 101 | "st_example.tex again." 102 | ] 103 | }, 104 | { 105 | "cell_type": "markdown", 106 | "id": "c273ba8e", 107 | "metadata": {}, 108 | "source": [ 109 | "Notice that, in addition to the usual collection of files produced by\n", 110 | "LaTeX, there is a file called `st_example.sagetex.sage`. That is a Sage\n", 111 | "script produced when you run LaTeX on `st_example.tex`. The warning\n", 112 | "message told you to run Sage on `st_example.sagetex.sage`, so take its\n", 113 | "advice and do that. It will tell you to run LaTeX on `st_example.tex`\n", 114 | "again, but before you do that, notice that a new file has been created:\n", 115 | "`st_example.sagetex.sout`. That file contains the results of Sage's\n", 116 | "computations, in a format that LaTeX can use to insert into your text. A\n", 117 | "new directory containing an EPS file of your plot has also been created.\n", 118 | "Run LaTeX again and you'll see that everything that Sage computed and\n", 119 | "plotted is now included in your document.\n", 120 | "\n", 121 | "The different macros used above should be pretty easy to understand. A\n", 122 | "`sageblock` environment typesets your code verbatim and also executes\n", 123 | "the code when you run Sage. When you do `\\sage{foo}`, the result put\n", 124 | "into your document is whatever you get from running `latex(foo)` inside\n", 125 | "Sage. Plot commands are a bit more complicated, but in their simplest\n", 126 | "form, `\\sageplot{foo}` inserts the image you get from doing\n", 127 | "`foo.save('filename.eps')`.\n", 128 | "\n", 129 | "In general, the mantra is:\n", 130 | "\n", 131 | "> - run LaTeX on your .tex file;\n", 132 | "> - run Sage on the generated .sage file;\n", 133 | "> - run LaTeX again.\n", 134 | "\n", 135 | "You can omit running Sage if you haven't changed around any Sage\n", 136 | "commands in your document.\n", 137 | "\n", 138 | "There's a lot more to SageTeX, and since both Sage and LaTeX are\n", 139 | "complex, powerful tools, it's a good idea to read the documentation for\n", 140 | "SageTeX, which is in `SAGE_ROOT/venv/share/doc/sagetex`.\n", 141 | "\n", 142 | "## Make SageTeX known to TeX\n", 143 | "\n", 144 | "Sage is largely self-contained, but some parts do need some intervention\n", 145 | "to work properly. SageTeX is one such part.\n", 146 | "\n", 147 | "The SageTeX package allows one to embed computations and plots from Sage\n", 148 | "into a LaTeX document. SageTeX is installed in Sage by default, but to\n", 149 | "use SageTeX with your LaTeX documents, you need to make your TeX\n", 150 | "installation aware of it before it will work.\n", 151 | "\n", 152 | "The key to this is that TeX needs to be able to find `sagetex.sty`,\n", 153 | "which can be found in `SAGE_ROOT/venv/share/texmf/tex/latex/sagetex/`,\n", 154 | "where `SAGE_ROOT` is the directory where you built or installed Sage. If\n", 155 | "TeX can find `sagetex.sty`, then SageTeX will work. There are several\n", 156 | "ways to accomplish this.\n", 157 | "\n", 158 | "- The first and simplest way is simply to copy `sagetex.sty` into the\n", 159 | " same directory as your LaTeX document. Since the current directory\n", 160 | " is always searched when typesetting a document, this will always\n", 161 | " work." 162 | ] 163 | }, 164 | { 165 | "cell_type": "markdown", 166 | "id": "b5bdc06f", 167 | "metadata": {}, 168 | "source": [ 169 | "\n", 170 | " There are a couple small problems with this, however: the first is\n", 171 | " that you will end up with many unnecessary copies of `sagetex.sty`\n", 172 | " scattered around your computer. The second and more serious problem\n", 173 | " is that if you upgrade Sage and get a new version of SageTeX, the\n", 174 | " Python code and LaTeX code for SageTeX may no longer match, causing\n", 175 | " errors.\n" 176 | ] 177 | }, 178 | { 179 | "cell_type": "markdown", 180 | "id": "42f9c8fc", 181 | "metadata": {}, 182 | "source": [ 183 | "- The second way is to use the `TEXINPUTS` environment variable. If\n", 184 | " you are using the bash shell, you can do" 185 | ] 186 | }, 187 | { 188 | "cell_type": "code", 189 | "execution_count": null, 190 | "id": "438619ec", 191 | "metadata": {}, 192 | "outputs": [], 193 | "source": [ 194 | " $ export TEXINPUTS=\"SAGE_ROOT/venv/share/texmf//:\"" 195 | ] 196 | }, 197 | { 198 | "cell_type": "markdown", 199 | "id": "6efcba75", 200 | "metadata": {}, 201 | "source": [ 202 | "\n", 203 | " where `SAGE_ROOT` is the location of your Sage installation. Note\n", 204 | " that the double slash and colon at the end of that line are\n", 205 | " important. Thereafter, TeX and friends will find the SageTeX style\n", 206 | " file. If you want to make this change permanent, you can add the\n", 207 | " above line to your `.bashrc` file. If you are using a different\n", 208 | " shell, you may have to modify the above command to make the\n", 209 | " environment variable known; see your shell's documentation for how\n", 210 | " to do that.\n", 211 | "\n", 212 | " One flaw with this method is that if you use applications like\n", 213 | " TeXShop, Kile, or Emacs/AucTeX, they will not necessarily pick up\n", 214 | " the environment variable, since when they run LaTeX, they may do so\n", 215 | " outside your usual shell environment.\n", 216 | "\n", 217 | " If you ever move your Sage installation, or install a new version\n", 218 | " into a new directory, you'll need to update the above command to\n", 219 | " reflect the new value of `SAGE_ROOT`.\n" 220 | ] 221 | }, 222 | { 223 | "cell_type": "markdown", 224 | "id": "33f3e6d5", 225 | "metadata": {}, 226 | "source": [ 227 | "- The third (and best) way to make TeX aware of `sagetex.sty` is to\n", 228 | " copy that file into a convenient place in your home directory. In\n", 229 | " most TeX distributions, the `texmf` directory in your home directory\n", 230 | " is automatically searched for packages. To find out exactly what\n", 231 | " this directory is, do the following on the command line:" 232 | ] 233 | }, 234 | { 235 | "cell_type": "code", 236 | "execution_count": null, 237 | "id": "c0437579", 238 | "metadata": {}, 239 | "outputs": [], 240 | "source": [ 241 | " $ kpsewhich -var-value=TEXMFHOME" 242 | ] 243 | }, 244 | { 245 | "cell_type": "markdown", 246 | "id": "cd4cfe66", 247 | "metadata": {}, 248 | "source": [ 249 | "\n", 250 | " which will print out a directory, such as `/home/drake/texmf` or\n", 251 | " `/Users/drake/Library/texmf`. Copy the `tex/` directory from\n", 252 | " `SAGE_ROOT/venv/share/texmf/` into your home `texmf` directory with\n", 253 | " a command like\n", 254 | "```{.python .input}\n", 255 | " $ cp -R SAGE_ROOT/venv/share/texmf/tex TEXMFHOME\n", 256 | "```\n", 257 | "\n", 258 | " where `SAGE_ROOT` is, as usual, replaced with the location of your\n", 259 | " Sage installation and `TEXMFHOME` is the result of the `kpsewhich`\n", 260 | " command above.\n", 261 | "\n", 262 | " If you upgrade Sage and discover that SageTeX no longer works, you\n", 263 | " can simply repeat these steps and the Sage and TeX parts of SageTeX\n", 264 | " will again be synchronized.\n" 265 | ] 266 | }, 267 | { 268 | "cell_type": "markdown", 269 | "id": "7c694a53", 270 | "metadata": {}, 271 | "source": [ 272 | "- For installation on a multiuser system, you just modify the above\n", 273 | " instructions appropriately to copy `sagetex.sty` into a systemwide\n", 274 | " TeX directory. Instead of the directory `TEXMFHOME`, probably the\n", 275 | " best choice is to use the result of" 276 | ] 277 | }, 278 | { 279 | "cell_type": "code", 280 | "execution_count": null, 281 | "id": "aa42039a", 282 | "metadata": {}, 283 | "outputs": [], 284 | "source": [ 285 | " $ kpsewhich -var-value=TEXMFLOCAL" 286 | ] 287 | }, 288 | { 289 | "cell_type": "markdown", 290 | "id": "efebbfa6", 291 | "metadata": {}, 292 | "source": [ 293 | "\n", 294 | " which will likely produce something like `/usr/local/share/texmf`.\n", 295 | " Copy the `tex` directory as above into the `TEXMFLOCAL` directory.\n", 296 | " Now you need to update TeX's database of packages, which you can do\n", 297 | " simply by running\n", 298 | "```{.python .input}\n", 299 | " $ texhash TEXMFLOCAL\n", 300 | "```\n", 301 | "\n", 302 | " as root, replacing `TEXMFLOCAL` appropriately. Now all users of your\n", 303 | " system will have access to the LaTeX package, and if they can also\n", 304 | " run Sage, they will be able to use SageTeX.\n" 305 | ] 306 | }, 307 | { 308 | "cell_type": "markdown", 309 | "id": "78eff5e6", 310 | "metadata": {}, 311 | "source": [ 312 | "Warning\n", 313 | "\n", 314 | "it's very important that the file `sagetex.sty` that LaTeX uses when\n", 315 | "typesetting your document match the version of SageTeX that Sage is\n", 316 | "using. If you upgrade your Sage installation, you really should delete\n", 317 | "all the old versions of `sagetex.sty` floating around.\n", 318 | "\n", 319 | "Because of this problem, we recommend copying the SageTeX files into\n", 320 | "your home directory's texmf directory (the third method above). Then\n", 321 | "there is only one thing you need to do (copy a directory) when you\n", 322 | "upgrade Sage to insure that SageTeX will work properly.\n", 323 | "\n", 324 | "## SageTeX documentation\n", 325 | "\n", 326 | "While not strictly part of installation, it bears mentioning here that\n", 327 | "the documentation for SageTeX is maintained in\n", 328 | "`SAGE_ROOT/venv/share/doc/sagetex/sagetex.pdf`. There is also an example\n", 329 | "file in the same directory -- see `example.tex` and `example.pdf`, the\n", 330 | "pre-built result of typesetting that file with LaTeX and Sage. You can\n", 331 | "also get those files from the [SageTeX\n", 332 | "page](https://github.com/sagemath/sagetex).\n", 333 | "\n", 334 | "## SageTeX and TeXLive\n", 335 | "\n", 336 | "One potentially confusing issue is that the popular TeX distribution\n", 337 | "[TeXLive 2009](http://www.tug.org/texlive/) includes SageTeX. This may\n", 338 | "seem nice, but with SageTeX, it's important that the Sage bits and LaTeX\n", 339 | "bits be synchronized -- which is a problem in this case, since both Sage\n", 340 | "and SageTeX are updated frequently, and TeXLive is not. While at the\n", 341 | "time of this writing (March 2013), many Linux distributions have moved\n", 342 | "on to more recent releases of TeXLive, the 2009 release lingers and is,\n", 343 | "in fact, the source of most bug reports about SageTeX!\n", 344 | "\n", 345 | "Because of this, it is *strongly recommended* that you always install\n", 346 | "the LaTeX part of SageTeX from Sage, as described above. The\n", 347 | "instructions above will insure that both halves of SageTeX are\n", 348 | "compatible and will work properly. Using TeXLive to provide the LaTeX\n", 349 | "side of SageTeX is not supported." 350 | ] 351 | } 352 | ], 353 | "metadata": {}, 354 | "nbformat": 4, 355 | "nbformat_minor": 5 356 | } 357 | -------------------------------------------------------------------------------- /resources/SageMath-tutorials/tour_rings.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "f5c5b9d2", 6 | "metadata": {}, 7 | "source": [ 8 | "$$\n", 9 | "\\def\\CC{\\bf C}\n", 10 | "\\def\\QQ{\\bf Q}\n", 11 | "\\def\\RR{\\bf R}\n", 12 | "\\def\\ZZ{\\bf Z}\n", 13 | "\\def\\NN{\\bf N}\n", 14 | "$$\n", 15 | "# Basic Rings\n", 16 | "\n", 17 | "When defining matrices, vectors, or polynomials, it is sometimes useful\n", 18 | "and sometimes necessary to specify the \"ring\" over which it is defined.\n", 19 | "A *ring* is a mathematical construction in which there are well-behaved\n", 20 | "notions of addition and multiplication; if you've never heard of them\n", 21 | "before, you probably just need to know about these four commonly used\n", 22 | "rings:\n", 23 | "\n", 24 | "- the integers $\\{..., -1, 0, 1, 2, ...\\}$, called `ZZ` in Sage.\n", 25 | "- the rational numbers -- i.e., fractions, or ratios, of integers\n", 26 | " --called `QQ` in Sage.\n", 27 | "- the real numbers, called `RR` in Sage.\n", 28 | "- the complex numbers, called `CC` in Sage.\n", 29 | "\n", 30 | "You may need to know about these distinctions because the same\n", 31 | "polynomial, for example, can be treated differently depending on the\n", 32 | "ring over which it is defined. For instance, the polynomial $x^2-2$ has\n", 33 | "two roots, $\\pm \\sqrt{2}$. Those roots are not rational, so if you are\n", 34 | "working with polynomials with rational coefficients, the polynomial\n", 35 | "won't factor. With real coefficients, it will. Therefore you may want to\n", 36 | "specify the ring to insure that you are getting the information you\n", 37 | "expect. The following two commands defines the sets of polynomials with\n", 38 | "rational coefficients and real coefficients, respectively. The sets are\n", 39 | "named \"ratpoly\" and \"realpoly\", but these aren't important here;\n", 40 | "however, note that the strings \".\\\" and \".\\\" name the\n", 41 | "*variables* used in the two cases. :" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": null, 47 | "id": "d30e7346", 48 | "metadata": {}, 49 | "outputs": [], 50 | "source": [ 51 | "ratpoly. = PolynomialRing(QQ)\n", 52 | "realpoly. = PolynomialRing(RR)" 53 | ] 54 | }, 55 | { 56 | "cell_type": "markdown", 57 | "id": "5bf4a1de", 58 | "metadata": {}, 59 | "source": [ 60 | "Now we illustrate the point about factoring $x^2-2$ :" 61 | ] 62 | }, 63 | { 64 | "cell_type": "code", 65 | "execution_count": null, 66 | "id": "aee7b04f", 67 | "metadata": {}, 68 | "outputs": [ 69 | { 70 | "data": { 71 | "text/plain": [ 72 | "t^2 - 2" 73 | ] 74 | }, 75 | "execution_count": 1, 76 | "metadata": {}, 77 | "output_type": "execute_result" 78 | } 79 | ], 80 | "source": [ 81 | "factor(t^2-2)" 82 | ] 83 | }, 84 | { 85 | "cell_type": "code", 86 | "execution_count": null, 87 | "id": "a166c3ef", 88 | "metadata": {}, 89 | "outputs": [ 90 | { 91 | "data": { 92 | "text/plain": [ 93 | "(z - 1.41421356237310) * (z + 1.41421356237310)" 94 | ] 95 | }, 96 | "execution_count": 1, 97 | "metadata": {}, 98 | "output_type": "execute_result" 99 | } 100 | ], 101 | "source": [ 102 | "factor(z^2-2)" 103 | ] 104 | }, 105 | { 106 | "cell_type": "markdown", 107 | "id": "d82e4645", 108 | "metadata": {}, 109 | "source": [ 110 | "Similar comments apply to matrices: the row-reduced form of a matrix can\n", 111 | "depend on the ring over which it is defined, as can its eigenvalues and\n", 112 | "eigenvectors. For more about constructing polynomials, see\n", 113 | "[section-poly](section-poly.ipynb), and for more about matrices, see\n", 114 | "[section-linalg](section-linalg.ipynb).\n", 115 | "\n", 116 | "The symbol `I` represents the square root of $-1$; `i` is a synonym for\n", 117 | "`I`. Of course, this is not a rational number:" 118 | ] 119 | }, 120 | { 121 | "cell_type": "code", 122 | "execution_count": null, 123 | "id": "5ffd5991", 124 | "metadata": {}, 125 | "outputs": [ 126 | { 127 | "data": { 128 | "text/plain": [ 129 | "I" 130 | ] 131 | }, 132 | "execution_count": 1, 133 | "metadata": {}, 134 | "output_type": "execute_result" 135 | } 136 | ], 137 | "source": [ 138 | "i # square root of -1" 139 | ] 140 | }, 141 | { 142 | "cell_type": "code", 143 | "execution_count": null, 144 | "id": "d2c21d14", 145 | "metadata": {}, 146 | "outputs": [ 147 | { 148 | "data": { 149 | "text/plain": [ 150 | "False" 151 | ] 152 | }, 153 | "execution_count": 1, 154 | "metadata": {}, 155 | "output_type": "execute_result" 156 | } 157 | ], 158 | "source": [ 159 | "i in QQ" 160 | ] 161 | }, 162 | { 163 | "cell_type": "markdown", 164 | "id": "64dcd80c", 165 | "metadata": {}, 166 | "source": [ 167 | "Note: The above code may not work as expected if the variable `i` has\n", 168 | "been assigned a different value, for example, if it was used as a loop\n", 169 | "variable. If this is the case, type :" 170 | ] 171 | }, 172 | { 173 | "cell_type": "code", 174 | "execution_count": null, 175 | "id": "f0c6a24e", 176 | "metadata": {}, 177 | "outputs": [], 178 | "source": [ 179 | "reset('i')" 180 | ] 181 | }, 182 | { 183 | "cell_type": "markdown", 184 | "id": "02112ccf", 185 | "metadata": {}, 186 | "source": [ 187 | "to get the original complex value of `i`.\n", 188 | "\n", 189 | "There is one subtlety in defining complex numbers: as mentioned above,\n", 190 | "the symbol `i` represents a square root of $-1$, but it is a *formal*\n", 191 | "square root of $-1$ as an algebraic number. Calling `CC(i)` or `CC.0` or\n", 192 | "`CC.gen(0)` returns the *complex* square root of $-1$. Arithmetic\n", 193 | "involving different kinds of numbers is possible by so-called coercion,\n", 194 | "see [section-coercion](section-coercion.ipynb)." 195 | ] 196 | }, 197 | { 198 | "cell_type": "code", 199 | "execution_count": null, 200 | "id": "aa89784e", 201 | "metadata": {}, 202 | "outputs": [ 203 | { 204 | "data": { 205 | "text/plain": [ 206 | "True" 207 | ] 208 | }, 209 | "execution_count": 1, 210 | "metadata": {}, 211 | "output_type": "execute_result" 212 | } 213 | ], 214 | "source": [ 215 | "i = CC(i) # floating point complex number\n", 216 | "i == CC.0" 217 | ] 218 | }, 219 | { 220 | "cell_type": "code", 221 | "execution_count": null, 222 | "id": "a4c0dda1", 223 | "metadata": {}, 224 | "outputs": [ 225 | { 226 | "data": { 227 | "text/plain": [ 228 | "1.33333333333333 + 0.666666666666667*I" 229 | ] 230 | }, 231 | "execution_count": 1, 232 | "metadata": {}, 233 | "output_type": "execute_result" 234 | } 235 | ], 236 | "source": [ 237 | "a, b = 4/3, 2/3\n", 238 | "z = a + b*i\n", 239 | "z" 240 | ] 241 | }, 242 | { 243 | "cell_type": "code", 244 | "execution_count": null, 245 | "id": "369219a3", 246 | "metadata": {}, 247 | "outputs": [ 248 | { 249 | "data": { 250 | "text/plain": [ 251 | "0.666666666666667" 252 | ] 253 | }, 254 | "execution_count": 1, 255 | "metadata": {}, 256 | "output_type": "execute_result" 257 | } 258 | ], 259 | "source": [ 260 | "z.imag() # imaginary part" 261 | ] 262 | }, 263 | { 264 | "cell_type": "code", 265 | "execution_count": null, 266 | "id": "2abe246b", 267 | "metadata": {}, 268 | "outputs": [ 269 | { 270 | "data": { 271 | "text/plain": [ 272 | "True" 273 | ] 274 | }, 275 | "execution_count": 1, 276 | "metadata": {}, 277 | "output_type": "execute_result" 278 | } 279 | ], 280 | "source": [ 281 | "z.real() == a # automatic coercion before comparison" 282 | ] 283 | }, 284 | { 285 | "cell_type": "code", 286 | "execution_count": null, 287 | "id": "1357ddc2", 288 | "metadata": {}, 289 | "outputs": [ 290 | { 291 | "data": { 292 | "text/plain": [ 293 | "2" 294 | ] 295 | }, 296 | "execution_count": 1, 297 | "metadata": {}, 298 | "output_type": "execute_result" 299 | } 300 | ], 301 | "source": [ 302 | "a + b" 303 | ] 304 | }, 305 | { 306 | "cell_type": "code", 307 | "execution_count": null, 308 | "id": "cebf6061", 309 | "metadata": {}, 310 | "outputs": [ 311 | { 312 | "data": { 313 | "text/plain": [ 314 | "True" 315 | ] 316 | }, 317 | "execution_count": 1, 318 | "metadata": {}, 319 | "output_type": "execute_result" 320 | } 321 | ], 322 | "source": [ 323 | "2*b == a" 324 | ] 325 | }, 326 | { 327 | "cell_type": "code", 328 | "execution_count": null, 329 | "id": "53f9ea0f", 330 | "metadata": {}, 331 | "outputs": [ 332 | { 333 | "data": { 334 | "text/plain": [ 335 | "Rational Field" 336 | ] 337 | }, 338 | "execution_count": 1, 339 | "metadata": {}, 340 | "output_type": "execute_result" 341 | } 342 | ], 343 | "source": [ 344 | "parent(2/3)" 345 | ] 346 | }, 347 | { 348 | "cell_type": "code", 349 | "execution_count": null, 350 | "id": "137f68b3", 351 | "metadata": {}, 352 | "outputs": [ 353 | { 354 | "data": { 355 | "text/plain": [ 356 | "Rational Field" 357 | ] 358 | }, 359 | "execution_count": 1, 360 | "metadata": {}, 361 | "output_type": "execute_result" 362 | } 363 | ], 364 | "source": [ 365 | "parent(4/2)" 366 | ] 367 | }, 368 | { 369 | "cell_type": "code", 370 | "execution_count": null, 371 | "id": "3267a9d4", 372 | "metadata": {}, 373 | "outputs": [ 374 | { 375 | "data": { 376 | "text/plain": [ 377 | "0.766666666666667" 378 | ] 379 | }, 380 | "execution_count": 1, 381 | "metadata": {}, 382 | "output_type": "execute_result" 383 | } 384 | ], 385 | "source": [ 386 | "2/3 + 0.1 # automatic coercion before addition" 387 | ] 388 | }, 389 | { 390 | "cell_type": "code", 391 | "execution_count": null, 392 | "id": "d6dfea88", 393 | "metadata": {}, 394 | "outputs": [ 395 | { 396 | "data": { 397 | "text/plain": [ 398 | "0.766666666666667" 399 | ] 400 | }, 401 | "execution_count": 1, 402 | "metadata": {}, 403 | "output_type": "execute_result" 404 | } 405 | ], 406 | "source": [ 407 | "0.1 + 2/3 # coercion rules are symmetric in Sage" 408 | ] 409 | }, 410 | { 411 | "cell_type": "markdown", 412 | "id": "fb9e6e52", 413 | "metadata": {}, 414 | "source": [ 415 | "Here are more examples of basic rings in Sage. As noted above, the ring\n", 416 | "of rational numbers may be referred to using `QQ`, or also\n", 417 | "`RationalField()` (a *field* is a ring in which the multiplication is\n", 418 | "commutative and in which every nonzero element has a reciprocal in that\n", 419 | "ring, so the rationals form a field, but the integers don't):" 420 | ] 421 | }, 422 | { 423 | "cell_type": "code", 424 | "execution_count": null, 425 | "id": "334093bb", 426 | "metadata": {}, 427 | "outputs": [ 428 | { 429 | "data": { 430 | "text/plain": [ 431 | "Rational Field" 432 | ] 433 | }, 434 | "execution_count": 1, 435 | "metadata": {}, 436 | "output_type": "execute_result" 437 | } 438 | ], 439 | "source": [ 440 | "RationalField()" 441 | ] 442 | }, 443 | { 444 | "cell_type": "code", 445 | "execution_count": null, 446 | "id": "0e272b5d", 447 | "metadata": {}, 448 | "outputs": [ 449 | { 450 | "data": { 451 | "text/plain": [ 452 | "Rational Field" 453 | ] 454 | }, 455 | "execution_count": 1, 456 | "metadata": {}, 457 | "output_type": "execute_result" 458 | } 459 | ], 460 | "source": [ 461 | "QQ" 462 | ] 463 | }, 464 | { 465 | "cell_type": "code", 466 | "execution_count": null, 467 | "id": "690e4e1f", 468 | "metadata": {}, 469 | "outputs": [ 470 | { 471 | "data": { 472 | "text/plain": [ 473 | "True" 474 | ] 475 | }, 476 | "execution_count": 1, 477 | "metadata": {}, 478 | "output_type": "execute_result" 479 | } 480 | ], 481 | "source": [ 482 | "1/2 in QQ" 483 | ] 484 | }, 485 | { 486 | "cell_type": "markdown", 487 | "id": "f3e8d01e", 488 | "metadata": {}, 489 | "source": [ 490 | "The decimal number `1.2` is considered to be in `QQ` : decimal numbers\n", 491 | "which happen to also be rational can be \"coerced\" into the rational\n", 492 | "numbers (see [section-coercion](section-coercion.ipynb)). The numbers\n", 493 | "$\\pi$ and $\\sqrt{2}$ are not rational, though:" 494 | ] 495 | }, 496 | { 497 | "cell_type": "code", 498 | "execution_count": null, 499 | "id": "0151d11a", 500 | "metadata": {}, 501 | "outputs": [ 502 | { 503 | "data": { 504 | "text/plain": [ 505 | "True" 506 | ] 507 | }, 508 | "execution_count": 1, 509 | "metadata": {}, 510 | "output_type": "execute_result" 511 | } 512 | ], 513 | "source": [ 514 | "1.2 in QQ" 515 | ] 516 | }, 517 | { 518 | "cell_type": "code", 519 | "execution_count": null, 520 | "id": "cbccd9d9", 521 | "metadata": {}, 522 | "outputs": [ 523 | { 524 | "data": { 525 | "text/plain": [ 526 | "False" 527 | ] 528 | }, 529 | "execution_count": 1, 530 | "metadata": {}, 531 | "output_type": "execute_result" 532 | } 533 | ], 534 | "source": [ 535 | "pi in QQ" 536 | ] 537 | }, 538 | { 539 | "cell_type": "code", 540 | "execution_count": null, 541 | "id": "c2b89368", 542 | "metadata": {}, 543 | "outputs": [ 544 | { 545 | "data": { 546 | "text/plain": [ 547 | "True" 548 | ] 549 | }, 550 | "execution_count": 1, 551 | "metadata": {}, 552 | "output_type": "execute_result" 553 | } 554 | ], 555 | "source": [ 556 | "pi in RR" 557 | ] 558 | }, 559 | { 560 | "cell_type": "code", 561 | "execution_count": null, 562 | "id": "a2d7627f", 563 | "metadata": {}, 564 | "outputs": [ 565 | { 566 | "data": { 567 | "text/plain": [ 568 | "False" 569 | ] 570 | }, 571 | "execution_count": 1, 572 | "metadata": {}, 573 | "output_type": "execute_result" 574 | } 575 | ], 576 | "source": [ 577 | "sqrt(2) in QQ" 578 | ] 579 | }, 580 | { 581 | "cell_type": "code", 582 | "execution_count": null, 583 | "id": "342e68a0", 584 | "metadata": {}, 585 | "outputs": [ 586 | { 587 | "data": { 588 | "text/plain": [ 589 | "True" 590 | ] 591 | }, 592 | "execution_count": 1, 593 | "metadata": {}, 594 | "output_type": "execute_result" 595 | } 596 | ], 597 | "source": [ 598 | "sqrt(2) in CC" 599 | ] 600 | }, 601 | { 602 | "cell_type": "markdown", 603 | "id": "7d8427cc", 604 | "metadata": {}, 605 | "source": [ 606 | "For use in higher mathematics, Sage also knows about other rings, such\n", 607 | "as finite fields, $p$-adic integers, the ring of algebraic numbers,\n", 608 | "polynomial rings, and matrix rings. Here are constructions of some of\n", 609 | "these:" 610 | ] 611 | }, 612 | { 613 | "cell_type": "code", 614 | "execution_count": null, 615 | "id": "397e1e44", 616 | "metadata": {}, 617 | "outputs": [ 618 | { 619 | "data": { 620 | "text/plain": [ 621 | "Finite Field of size 3" 622 | ] 623 | }, 624 | "execution_count": 1, 625 | "metadata": {}, 626 | "output_type": "execute_result" 627 | } 628 | ], 629 | "source": [ 630 | "GF(3)" 631 | ] 632 | }, 633 | { 634 | "cell_type": "code", 635 | "execution_count": null, 636 | "id": "f9ae2773", 637 | "metadata": {}, 638 | "outputs": [ 639 | { 640 | "data": { 641 | "text/plain": [ 642 | "Finite Field in a of size 3^3" 643 | ] 644 | }, 645 | "execution_count": 1, 646 | "metadata": {}, 647 | "output_type": "execute_result" 648 | } 649 | ], 650 | "source": [ 651 | "GF(27, 'a') # need to name the generator if not a prime field" 652 | ] 653 | }, 654 | { 655 | "cell_type": "code", 656 | "execution_count": null, 657 | "id": "f9e88c42", 658 | "metadata": {}, 659 | "outputs": [ 660 | { 661 | "data": { 662 | "text/plain": [ 663 | "5-adic Ring with capped relative precision 20" 664 | ] 665 | }, 666 | "execution_count": 1, 667 | "metadata": {}, 668 | "output_type": "execute_result" 669 | } 670 | ], 671 | "source": [ 672 | "Zp(5)" 673 | ] 674 | }, 675 | { 676 | "cell_type": "code", 677 | "execution_count": null, 678 | "id": "45358b93", 679 | "metadata": {}, 680 | "outputs": [ 681 | { 682 | "data": { 683 | "text/plain": [ 684 | "True" 685 | ] 686 | }, 687 | "execution_count": 1, 688 | "metadata": {}, 689 | "output_type": "execute_result" 690 | } 691 | ], 692 | "source": [ 693 | "sqrt(3) in QQbar # algebraic closure of QQ" 694 | ] 695 | } 696 | ], 697 | "metadata": {}, 698 | "nbformat": 4, 699 | "nbformat_minor": 5 700 | } 701 | -------------------------------------------------------------------------------- /resources/SageMath-tutorials/tour_plotting.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "46a8c274", 6 | "metadata": {}, 7 | "source": [ 8 | "$$\n", 9 | "\\def\\CC{\\bf C}\n", 10 | "\\def\\QQ{\\bf Q}\n", 11 | "\\def\\RR{\\bf R}\n", 12 | "\\def\\ZZ{\\bf Z}\n", 13 | "\\def\\NN{\\bf N}\n", 14 | "$$\n", 15 | "# Plotting\n", 16 | "\n", 17 | "Sage can produce two-dimensional and three-dimensional plots.\n", 18 | "\n", 19 | "## Two-dimensional Plots\n", 20 | "\n", 21 | "In two dimensions, Sage can draw circles, lines, and polygons; plots of\n", 22 | "functions in rectangular coordinates; and also polar plots, contour\n", 23 | "plots and vector field plots. We present examples of some of these here.\n", 24 | "For more examples of plotting with Sage, see\n", 25 | "[section-systems](section-systems.ipynb) and\n", 26 | "[section-maxima](section-maxima.ipynb), and also the [Sage\n", 27 | "Constructions](http://doc.sagemath.org/html/en/constructions/)\n", 28 | "documentation.\n", 29 | "\n", 30 | "This command produces a yellow circle of radius 1, centered at the\n", 31 | "origin:" 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "execution_count": null, 37 | "id": "4b028848", 38 | "metadata": {}, 39 | "outputs": [ 40 | { 41 | "data": { 42 | "text/plain": [ 43 | "Graphics object consisting of 1 graphics primitive" 44 | ] 45 | }, 46 | "execution_count": 1, 47 | "metadata": {}, 48 | "output_type": "execute_result" 49 | } 50 | ], 51 | "source": [ 52 | "circle((0,0), 1, rgbcolor=(1,1,0))" 53 | ] 54 | }, 55 | { 56 | "cell_type": "markdown", 57 | "id": "d72958ee", 58 | "metadata": {}, 59 | "source": [ 60 | "You can also produce a filled circle:" 61 | ] 62 | }, 63 | { 64 | "cell_type": "code", 65 | "execution_count": null, 66 | "id": "d24c78b9", 67 | "metadata": {}, 68 | "outputs": [ 69 | { 70 | "data": { 71 | "text/plain": [ 72 | "Graphics object consisting of 1 graphics primitive" 73 | ] 74 | }, 75 | "execution_count": 1, 76 | "metadata": {}, 77 | "output_type": "execute_result" 78 | } 79 | ], 80 | "source": [ 81 | "circle((0,0), 1, rgbcolor=(1,1,0), fill=True)" 82 | ] 83 | }, 84 | { 85 | "cell_type": "markdown", 86 | "id": "dfb4bceb", 87 | "metadata": {}, 88 | "source": [ 89 | "You can also create a circle by assigning it to a variable; this does\n", 90 | "not plot it:" 91 | ] 92 | }, 93 | { 94 | "cell_type": "code", 95 | "execution_count": null, 96 | "id": "ef2a7172", 97 | "metadata": {}, 98 | "outputs": [], 99 | "source": [ 100 | "c = circle((0,0), 1, rgbcolor=(1,1,0))" 101 | ] 102 | }, 103 | { 104 | "cell_type": "markdown", 105 | "id": "0235b765", 106 | "metadata": {}, 107 | "source": [ 108 | "To plot it, use `c.show()` or `show(c)`, as follows:" 109 | ] 110 | }, 111 | { 112 | "cell_type": "code", 113 | "execution_count": null, 114 | "id": "9fca3e26", 115 | "metadata": {}, 116 | "outputs": [], 117 | "source": [ 118 | "c.show()" 119 | ] 120 | }, 121 | { 122 | "cell_type": "markdown", 123 | "id": "f5021464", 124 | "metadata": {}, 125 | "source": [ 126 | "Alternatively, evaluating `c.save('filename.png')` will save the plot to\n", 127 | "the given file.\n", 128 | "\n", 129 | "Now, these 'circles' look more like ellipses because the axes are scaled\n", 130 | "differently. You can fix this:" 131 | ] 132 | }, 133 | { 134 | "cell_type": "code", 135 | "execution_count": null, 136 | "id": "26ed0f5d", 137 | "metadata": {}, 138 | "outputs": [], 139 | "source": [ 140 | "c.show(aspect_ratio=1)" 141 | ] 142 | }, 143 | { 144 | "cell_type": "markdown", 145 | "id": "9ff17c60", 146 | "metadata": {}, 147 | "source": [ 148 | "The command `show(c, aspect_ratio=1)` accomplishes the same thing, or\n", 149 | "you can save the picture using `c.save('filename.png', aspect_ratio=1)`.\n", 150 | "\n", 151 | "It's easy to plot basic functions:" 152 | ] 153 | }, 154 | { 155 | "cell_type": "code", 156 | "execution_count": null, 157 | "id": "1da0cf2e", 158 | "metadata": {}, 159 | "outputs": [ 160 | { 161 | "data": { 162 | "text/plain": [ 163 | "Graphics object consisting of 1 graphics primitive" 164 | ] 165 | }, 166 | "execution_count": 1, 167 | "metadata": {}, 168 | "output_type": "execute_result" 169 | } 170 | ], 171 | "source": [ 172 | "plot(cos, (-5,5))" 173 | ] 174 | }, 175 | { 176 | "cell_type": "markdown", 177 | "id": "4766f41e", 178 | "metadata": {}, 179 | "source": [ 180 | "Once you specify a variable name, you can create parametric plots also:" 181 | ] 182 | }, 183 | { 184 | "cell_type": "code", 185 | "execution_count": null, 186 | "id": "312a670e", 187 | "metadata": {}, 188 | "outputs": [ 189 | { 190 | "data": { 191 | "text/plain": [ 192 | "Graphics object consisting of 1 graphics primitive" 193 | ] 194 | }, 195 | "execution_count": 1, 196 | "metadata": {}, 197 | "output_type": "execute_result" 198 | } 199 | ], 200 | "source": [ 201 | "x = var('x')\n", 202 | "parametric_plot((cos(x),sin(x)^3),(x,0,2*pi),rgbcolor=hue(0.6))" 203 | ] 204 | }, 205 | { 206 | "cell_type": "markdown", 207 | "id": "5db036f6", 208 | "metadata": {}, 209 | "source": [ 210 | "It's important to notice that the axes of the plots will only intersect\n", 211 | "if the origin is in the viewing range of the graph, and that with\n", 212 | "sufficiently large values scientific notation may be used:" 213 | ] 214 | }, 215 | { 216 | "cell_type": "code", 217 | "execution_count": null, 218 | "id": "e1301dce", 219 | "metadata": {}, 220 | "outputs": [ 221 | { 222 | "data": { 223 | "text/plain": [ 224 | "Graphics object consisting of 1 graphics primitive" 225 | ] 226 | }, 227 | "execution_count": 1, 228 | "metadata": {}, 229 | "output_type": "execute_result" 230 | } 231 | ], 232 | "source": [ 233 | "plot(x^2,(x,300,500))" 234 | ] 235 | }, 236 | { 237 | "cell_type": "markdown", 238 | "id": "5c438747", 239 | "metadata": {}, 240 | "source": [ 241 | "You can combine several plots by adding them:" 242 | ] 243 | }, 244 | { 245 | "cell_type": "code", 246 | "execution_count": null, 247 | "id": "0229312f", 248 | "metadata": {}, 249 | "outputs": [], 250 | "source": [ 251 | "x = var('x')\n", 252 | "p1 = parametric_plot((cos(x),sin(x)),(x,0,2*pi),rgbcolor=hue(0.2))\n", 253 | "p2 = parametric_plot((cos(x),sin(x)^2),(x,0,2*pi),rgbcolor=hue(0.4))\n", 254 | "p3 = parametric_plot((cos(x),sin(x)^3),(x,0,2*pi),rgbcolor=hue(0.6))\n", 255 | "show(p1+p2+p3, axes=false)" 256 | ] 257 | }, 258 | { 259 | "cell_type": "markdown", 260 | "id": "22ea87f7", 261 | "metadata": {}, 262 | "source": [ 263 | "A good way to produce filled-in shapes is to produce a list of points\n", 264 | "(`L` in the example below) and then use the `polygon` command to plot\n", 265 | "the shape with boundary formed by those points. For example, here is a\n", 266 | "green deltoid:" 267 | ] 268 | }, 269 | { 270 | "cell_type": "code", 271 | "execution_count": null, 272 | "id": "3ac34d26", 273 | "metadata": {}, 274 | "outputs": [ 275 | { 276 | "data": { 277 | "text/plain": [ 278 | "Graphics object consisting of 1 graphics primitive" 279 | ] 280 | }, 281 | "execution_count": 1, 282 | "metadata": {}, 283 | "output_type": "execute_result" 284 | } 285 | ], 286 | "source": [ 287 | "L = [[-1+cos(pi*i/100)*(1+cos(pi*i/100)),\n", 288 | " 2*sin(pi*i/100)*(1-cos(pi*i/100))] for i in range(200)]\n", 289 | "p = polygon(L, rgbcolor=(1/8,3/4,1/2))\n", 290 | "p" 291 | ] 292 | }, 293 | { 294 | "cell_type": "markdown", 295 | "id": "8294c444", 296 | "metadata": {}, 297 | "source": [ 298 | "Type `show(p, axes=false)` to see this without any axes.\n", 299 | "\n", 300 | "You can add text to a plot:" 301 | ] 302 | }, 303 | { 304 | "cell_type": "code", 305 | "execution_count": null, 306 | "id": "188c5cc5", 307 | "metadata": {}, 308 | "outputs": [], 309 | "source": [ 310 | "L = [[6*cos(pi*i/100)+5*cos((6/2)*pi*i/100),\n", 311 | " 6*sin(pi*i/100)-5*sin((6/2)*pi*i/100)] for i in range(200)]\n", 312 | "p = polygon(L, rgbcolor=(1/8,1/4,1/2))\n", 313 | "t = text(\"hypotrochoid\", (5,4), rgbcolor=(1,0,0))\n", 314 | "show(p+t)" 315 | ] 316 | }, 317 | { 318 | "cell_type": "markdown", 319 | "id": "c6dc830d", 320 | "metadata": {}, 321 | "source": [ 322 | "Calculus teachers draw the following plot frequently on the board: not\n", 323 | "just one branch of arcsin but rather several of them: i.e., the plot of\n", 324 | "$y=\\sin(x)$ for $x$ between $-2\\pi$ and $2\\pi$, flipped about the 45\n", 325 | "degree line. The following Sage commands construct this:" 326 | ] 327 | }, 328 | { 329 | "cell_type": "code", 330 | "execution_count": null, 331 | "id": "c87892b6", 332 | "metadata": {}, 333 | "outputs": [ 334 | { 335 | "data": { 336 | "text/plain": [ 337 | "Graphics object consisting of 1 graphics primitive" 338 | ] 339 | }, 340 | "execution_count": 1, 341 | "metadata": {}, 342 | "output_type": "execute_result" 343 | } 344 | ], 345 | "source": [ 346 | "v = [(sin(x),x) for x in srange(-2*float(pi),2*float(pi),0.1)]\n", 347 | "line(v)" 348 | ] 349 | }, 350 | { 351 | "cell_type": "markdown", 352 | "id": "83bd7236", 353 | "metadata": {}, 354 | "source": [ 355 | "Since the tangent function has a larger range than sine, if you use the\n", 356 | "same trick to plot the inverse tangent, you should change the minimum\n", 357 | "and maximum coordinates for the *x*-axis:" 358 | ] 359 | }, 360 | { 361 | "cell_type": "code", 362 | "execution_count": null, 363 | "id": "18a8f5c0", 364 | "metadata": {}, 365 | "outputs": [], 366 | "source": [ 367 | "v = [(tan(x),x) for x in srange(-2*float(pi),2*float(pi),0.01)]\n", 368 | "show(line(v), xmin=-20, xmax=20)" 369 | ] 370 | }, 371 | { 372 | "cell_type": "markdown", 373 | "id": "1b76e55e", 374 | "metadata": {}, 375 | "source": [ 376 | "Sage also computes polar plots, contour plots and vector field plots\n", 377 | "(for special types of functions). Here is an example of a contour plot:" 378 | ] 379 | }, 380 | { 381 | "cell_type": "code", 382 | "execution_count": null, 383 | "id": "0df5286f", 384 | "metadata": {}, 385 | "outputs": [ 386 | { 387 | "data": { 388 | "text/plain": [ 389 | "Graphics object consisting of 1 graphics primitive" 390 | ] 391 | }, 392 | "execution_count": 1, 393 | "metadata": {}, 394 | "output_type": "execute_result" 395 | } 396 | ], 397 | "source": [ 398 | "f = lambda x,y: cos(x*y)\n", 399 | "contour_plot(f, (-4, 4), (-4, 4))" 400 | ] 401 | }, 402 | { 403 | "cell_type": "markdown", 404 | "id": "072d78e7", 405 | "metadata": {}, 406 | "source": [ 407 | "## Three-Dimensional Plots\n", 408 | "\n", 409 | "Sage can also be used to create three-dimensional plots. In both the\n", 410 | "notebook and the REPL, these plots will be displayed by default using\n", 411 | "the open source package [\\[ThreeJS\\]](), which supports interactively\n", 412 | "rotating and zooming the figure with the mouse.\n", 413 | "\n", 414 | "Use `plot3d` to graph a function of the form $f(x, y) = z$ :" 415 | ] 416 | }, 417 | { 418 | "cell_type": "code", 419 | "execution_count": null, 420 | "id": "e8bd7a74", 421 | "metadata": {}, 422 | "outputs": [ 423 | { 424 | "data": { 425 | "text/plain": [ 426 | "Graphics3d Object" 427 | ] 428 | }, 429 | "execution_count": 1, 430 | "metadata": {}, 431 | "output_type": "execute_result" 432 | } 433 | ], 434 | "source": [ 435 | "x, y = var('x,y')\n", 436 | "plot3d(x^2 + y^2, (x,-2,2), (y,-2,2))" 437 | ] 438 | }, 439 | { 440 | "cell_type": "markdown", 441 | "id": "0d537314", 442 | "metadata": {}, 443 | "source": [ 444 | "Alternatively, you can use `parametric_plot3d` to graph a parametric\n", 445 | "surface where each of $x, y, z$ is determined by a function of one or\n", 446 | "two variables (the parameters, typically $u$ and $v$). The previous plot\n", 447 | "can be expressed parametrically as follows:" 448 | ] 449 | }, 450 | { 451 | "cell_type": "code", 452 | "execution_count": null, 453 | "id": "f7123824", 454 | "metadata": {}, 455 | "outputs": [ 456 | { 457 | "data": { 458 | "text/plain": [ 459 | "Graphics3d Object" 460 | ] 461 | }, 462 | "execution_count": 1, 463 | "metadata": {}, 464 | "output_type": "execute_result" 465 | } 466 | ], 467 | "source": [ 468 | "u, v = var('u, v')\n", 469 | "f_x(u, v) = u\n", 470 | "f_y(u, v) = v\n", 471 | "f_z(u, v) = u^2 + v^2\n", 472 | "parametric_plot3d([f_x, f_y, f_z], (u, -2, 2), (v, -2, 2))" 473 | ] 474 | }, 475 | { 476 | "cell_type": "markdown", 477 | "id": "f8ed31c6", 478 | "metadata": {}, 479 | "source": [ 480 | "The third way to plot a 3D surface in Sage is `implicit_plot3d`, which\n", 481 | "graphs a contour of a function like $f(x, y, z) = 0$ (this defines a set\n", 482 | "of points). We graph a sphere using the classical formula:" 483 | ] 484 | }, 485 | { 486 | "cell_type": "code", 487 | "execution_count": null, 488 | "id": "86176aa4", 489 | "metadata": {}, 490 | "outputs": [ 491 | { 492 | "data": { 493 | "text/plain": [ 494 | "Graphics3d Object" 495 | ] 496 | }, 497 | "execution_count": 1, 498 | "metadata": {}, 499 | "output_type": "execute_result" 500 | } 501 | ], 502 | "source": [ 503 | "x, y, z = var('x, y, z')\n", 504 | "implicit_plot3d(x^2 + y^2 + z^2 - 4, (x,-2, 2), (y,-2, 2), (z,-2, 2))" 505 | ] 506 | }, 507 | { 508 | "cell_type": "markdown", 509 | "id": "2fc37d10", 510 | "metadata": {}, 511 | "source": [ 512 | "Here are some more examples:\n", 513 | "\n", 514 | "[Yellow Whitney's\n", 515 | "umbrella](http://en.wikipedia.org/wiki/Whitney_umbrella):" 516 | ] 517 | }, 518 | { 519 | "cell_type": "code", 520 | "execution_count": null, 521 | "id": "29f97ab6", 522 | "metadata": {}, 523 | "outputs": [ 524 | { 525 | "data": { 526 | "text/plain": [ 527 | "Graphics3d Object" 528 | ] 529 | }, 530 | "execution_count": 1, 531 | "metadata": {}, 532 | "output_type": "execute_result" 533 | } 534 | ], 535 | "source": [ 536 | "u, v = var('u,v')\n", 537 | "fx = u*v\n", 538 | "fy = u\n", 539 | "fz = v^2\n", 540 | "parametric_plot3d([fx, fy, fz], (u, -1, 1), (v, -1, 1),\n", 541 | " frame=False, color=\"yellow\")" 542 | ] 543 | }, 544 | { 545 | "cell_type": "markdown", 546 | "id": "7dfdb42f", 547 | "metadata": {}, 548 | "source": [ 549 | "[Cross cap](http://en.wikipedia.org/wiki/Cross-cap):" 550 | ] 551 | }, 552 | { 553 | "cell_type": "code", 554 | "execution_count": null, 555 | "id": "4cbe792c", 556 | "metadata": {}, 557 | "outputs": [ 558 | { 559 | "data": { 560 | "text/plain": [ 561 | "Graphics3d Object" 562 | ] 563 | }, 564 | "execution_count": 1, 565 | "metadata": {}, 566 | "output_type": "execute_result" 567 | } 568 | ], 569 | "source": [ 570 | "u, v = var('u,v')\n", 571 | "fx = (1+cos(v))*cos(u)\n", 572 | "fy = (1+cos(v))*sin(u)\n", 573 | "fz = -tanh((2/3)*(u-pi))*sin(v)\n", 574 | "parametric_plot3d([fx, fy, fz], (u, 0, 2*pi), (v, 0, 2*pi),\n", 575 | " frame=False, color=\"red\")" 576 | ] 577 | }, 578 | { 579 | "cell_type": "markdown", 580 | "id": "fb30ac27", 581 | "metadata": {}, 582 | "source": [ 583 | "Twisted torus:" 584 | ] 585 | }, 586 | { 587 | "cell_type": "code", 588 | "execution_count": null, 589 | "id": "a9ab1404", 590 | "metadata": {}, 591 | "outputs": [ 592 | { 593 | "data": { 594 | "text/plain": [ 595 | "Graphics3d Object" 596 | ] 597 | }, 598 | "execution_count": 1, 599 | "metadata": {}, 600 | "output_type": "execute_result" 601 | } 602 | ], 603 | "source": [ 604 | "u, v = var('u,v')\n", 605 | "fx = (3+sin(v)+cos(u))*cos(2*v)\n", 606 | "fy = (3+sin(v)+cos(u))*sin(2*v)\n", 607 | "fz = sin(u)+2*cos(v)\n", 608 | "parametric_plot3d([fx, fy, fz], (u, 0, 2*pi), (v, 0, 2*pi),\n", 609 | " frame=False, color=\"red\")" 610 | ] 611 | }, 612 | { 613 | "cell_type": "markdown", 614 | "id": "7252eb3b", 615 | "metadata": {}, 616 | "source": [ 617 | "Lemniscate:" 618 | ] 619 | }, 620 | { 621 | "cell_type": "code", 622 | "execution_count": null, 623 | "id": "7bab43cf", 624 | "metadata": {}, 625 | "outputs": [ 626 | { 627 | "data": { 628 | "text/plain": [ 629 | "Graphics3d Object" 630 | ] 631 | }, 632 | "execution_count": 1, 633 | "metadata": {}, 634 | "output_type": "execute_result" 635 | } 636 | ], 637 | "source": [ 638 | "x, y, z = var('x,y,z')\n", 639 | "f(x, y, z) = 4*x^2 * (x^2 + y^2 + z^2 + z) + y^2 * (y^2 + z^2 - 1)\n", 640 | "implicit_plot3d(f, (x, -0.5, 0.5), (y, -1, 1), (z, -1, 1))" 641 | ] 642 | } 643 | ], 644 | "metadata": {}, 645 | "nbformat": 4, 646 | "nbformat_minor": 5 647 | } 648 | -------------------------------------------------------------------------------- /resources/SageMath-thematic-tutorials/TikzPicture-and-more.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "770cfe2e", 6 | "metadata": { 7 | "slideshow": { 8 | "slide_type": "slide" 9 | } 10 | }, 11 | "source": [ 12 | "# Some more nice features of Python/SageMath\n", 13 | "\n", 14 | "**Sébastien Labbé**\n", 15 | "\n", 16 | "February 9, 2023, Le Teich, Maison de la nature\n", 17 | "\n", 18 | "Outline:\n", 19 | "\n", 20 | "1. nbviewer.org\n", 21 | "2. RISE : turning a Jupyter notebook into a Slide Presentation\n", 22 | "3. `table`\n", 23 | "3. `TikzPicture` in Sage\n", 24 | "4. `RecursivelyEnumeratedSet`" 25 | ] 26 | }, 27 | { 28 | "cell_type": "markdown", 29 | "id": "b1bbca0e", 30 | "metadata": { 31 | "slideshow": { 32 | "slide_type": "slide" 33 | } 34 | }, 35 | "source": [ 36 | "# 1. nbviewer.org\n", 37 | "\n", 38 | "\n", 39 | "https://nbviewer.org/\n", 40 | "\n", 41 | "https://nbviewer.org/url/www.slabbe.org/Publications/arXiv_1906_01104.ipynb" 42 | ] 43 | }, 44 | { 45 | "cell_type": "markdown", 46 | "id": "555e7e57", 47 | "metadata": { 48 | "slideshow": { 49 | "slide_type": "slide" 50 | } 51 | }, 52 | "source": [ 53 | "# 2. RISE : turning a Jupyter notebook into a Slide Presentation\n", 54 | "\n", 55 | "`pip install rise`\n", 56 | "\n", 57 | "For documentation, see the video shown on the project page https://pypi.org/project/rise/\n", 58 | "\n", 59 | "One example:\n", 60 | "\n", 61 | " - http://www.slabbe.org/Communications/2021-01-cirm.ipynb\n", 62 | " - http://www.slabbe.org/Communications/2021-01-cirm.pdf\n", 63 | " - http://www.slabbe.org/Communications/2021-01-cirm.slides.html" 64 | ] 65 | }, 66 | { 67 | "cell_type": "markdown", 68 | "id": "8e6fda90", 69 | "metadata": { 70 | "slideshow": { 71 | "slide_type": "slide" 72 | } 73 | }, 74 | "source": [ 75 | "# 3. table in Sage\n" 76 | ] 77 | }, 78 | { 79 | "cell_type": "code", 80 | "execution_count": null, 81 | "id": "9a16b97c", 82 | "metadata": {}, 83 | "outputs": [], 84 | "source": [ 85 | "for i in range(1000, 1050):\n", 86 | " print(i, factor(i), i^2, is_prime(i))" 87 | ] 88 | }, 89 | { 90 | "cell_type": "code", 91 | "execution_count": null, 92 | "id": "2042de7c", 93 | "metadata": {}, 94 | "outputs": [], 95 | "source": [ 96 | "rows = []\n", 97 | "for i in range(1000, 1050):\n", 98 | " row = (i, factor(i), i^2, is_prime(i))\n", 99 | " rows.append(row)\n", 100 | "header_row = ['n', 'factor(n)', 'n^2', 'is_prime(n)']\n", 101 | "t = table(rows, header_row=header_row)\n", 102 | "t" 103 | ] 104 | }, 105 | { 106 | "cell_type": "markdown", 107 | "id": "6cd12861", 108 | "metadata": { 109 | "slideshow": { 110 | "slide_type": "slide" 111 | } 112 | }, 113 | "source": [ 114 | "# 4. TikzPicture in Sage\n", 115 | "\n", 116 | "Merged in sagemath-9.6 (trac ticket: https://trac.sagemath.org/ticket/20343)" 117 | ] 118 | }, 119 | { 120 | "cell_type": "code", 121 | "execution_count": null, 122 | "id": "e59f037f", 123 | "metadata": {}, 124 | "outputs": [], 125 | "source": [ 126 | "from sage.misc.latex_standalone import TikzPicture\n", 127 | "#!pip install slabbe # with sagemath version < 9.6\n", 128 | "#from slabbe import TikzPicture # with sagemath version < 9.6" 129 | ] 130 | }, 131 | { 132 | "cell_type": "markdown", 133 | "id": "cae59811", 134 | "metadata": { 135 | "slideshow": { 136 | "slide_type": "subslide" 137 | } 138 | }, 139 | "source": [ 140 | "## Baby example" 141 | ] 142 | }, 143 | { 144 | "cell_type": "code", 145 | "execution_count": null, 146 | "id": "0dddd60e", 147 | "metadata": {}, 148 | "outputs": [], 149 | "source": [ 150 | "lines = []\n", 151 | "lines.append(r\"\\begin{tikzpicture}\")\n", 152 | "lines.append(r\"\\draw[->] (0,0) -- (10,1);\")\n", 153 | "lines.append(r\"\\end{tikzpicture}\")\n", 154 | "s = '\\n'.join(lines)\n", 155 | "print(s)" 156 | ] 157 | }, 158 | { 159 | "cell_type": "code", 160 | "execution_count": null, 161 | "id": "25651688", 162 | "metadata": { 163 | "slideshow": { 164 | "slide_type": "fragment" 165 | } 166 | }, 167 | "outputs": [], 168 | "source": [ 169 | "t = TikzPicture(s)" 170 | ] 171 | }, 172 | { 173 | "cell_type": "code", 174 | "execution_count": null, 175 | "id": "fbcd14a6", 176 | "metadata": { 177 | "slideshow": { 178 | "slide_type": "fragment" 179 | } 180 | }, 181 | "outputs": [], 182 | "source": [ 183 | "print(TikzPicture(s))" 184 | ] 185 | }, 186 | { 187 | "cell_type": "code", 188 | "execution_count": null, 189 | "id": "34424a41", 190 | "metadata": {}, 191 | "outputs": [], 192 | "source": [ 193 | "TikzPicture(s, standalone_config=[\"border=5mm\"])" 194 | ] 195 | }, 196 | { 197 | "cell_type": "code", 198 | "execution_count": null, 199 | "id": "193a68f8", 200 | "metadata": {}, 201 | "outputs": [], 202 | "source": [ 203 | "t.tex('file.tex', content_only=True)" 204 | ] 205 | }, 206 | { 207 | "cell_type": "markdown", 208 | "id": "b1e24cdf", 209 | "metadata": { 210 | "slideshow": { 211 | "slide_type": "subslide" 212 | } 213 | }, 214 | "source": [ 215 | "## Random walk" 216 | ] 217 | }, 218 | { 219 | "cell_type": "code", 220 | "execution_count": null, 221 | "id": "2f89e261", 222 | "metadata": {}, 223 | "outputs": [], 224 | "source": [ 225 | "def random_walk(steps, length, start=(0,0)):\n", 226 | " p = vector(start)\n", 227 | " L = [p]\n", 228 | " for _ in range(length):\n", 229 | " step = choice(steps)\n", 230 | " p += step\n", 231 | " L.append(p)\n", 232 | " return L" 233 | ] 234 | }, 235 | { 236 | "cell_type": "code", 237 | "execution_count": null, 238 | "id": "be98b568", 239 | "metadata": {}, 240 | "outputs": [], 241 | "source": [ 242 | "steps = [vector((1,0)), vector((0,1))]\n", 243 | "L = random_walk(steps, 10)\n", 244 | "L" 245 | ] 246 | }, 247 | { 248 | "cell_type": "code", 249 | "execution_count": null, 250 | "id": "1ad9c3c2", 251 | "metadata": {}, 252 | "outputs": [], 253 | "source": [ 254 | "' -- '.join(str(p) for p in L)" 255 | ] 256 | }, 257 | { 258 | "cell_type": "code", 259 | "execution_count": null, 260 | "id": "c163f8f5", 261 | "metadata": { 262 | "slideshow": { 263 | "slide_type": "subslide" 264 | } 265 | }, 266 | "outputs": [], 267 | "source": [ 268 | "def walk_to_tikz(L):\n", 269 | " lines = []\n", 270 | " lines.append(r\"\\begin{tikzpicture}\")\n", 271 | " lines.append(r\"\\draw[->] {};\".format(' -- '.join(str(p) for p in L)))\n", 272 | " lines.append(r\"\\end{tikzpicture}\")\n", 273 | " s = '\\n'.join(lines)\n", 274 | " return TikzPicture(s, standalone_config=[\"border=5mm\"])" 275 | ] 276 | }, 277 | { 278 | "cell_type": "code", 279 | "execution_count": null, 280 | "id": "8dfe0e9f", 281 | "metadata": {}, 282 | "outputs": [], 283 | "source": [ 284 | "L = random_walk(steps, 10)\n", 285 | "walk_to_tikz(L)" 286 | ] 287 | }, 288 | { 289 | "cell_type": "markdown", 290 | "id": "8d453991", 291 | "metadata": { 292 | "slideshow": { 293 | "slide_type": "subslide" 294 | } 295 | }, 296 | "source": [ 297 | "## Polytopes\n", 298 | "\n", 299 | "https://jplab.github.io/polytope.html\n", 300 | "\n", 301 | "Thematic tutorial: https://doc.sagemath.org/html/en/thematic_tutorials/geometry/polytope_tikz.html" 302 | ] 303 | }, 304 | { 305 | "cell_type": "code", 306 | "execution_count": null, 307 | "id": "f31178c0", 308 | "metadata": {}, 309 | "outputs": [], 310 | "source": [ 311 | "V = [[1,0,1],[1,0,0],[1,1,0],[0,0,-1],[0,1,0],[-1,0,0],[0,1,1],[0,0,1],[0,-1,0]]\n", 312 | "P = Polyhedron(vertices=V).polar()\n", 313 | "P.plot()" 314 | ] 315 | }, 316 | { 317 | "cell_type": "code", 318 | "execution_count": null, 319 | "id": "e166d82c", 320 | "metadata": {}, 321 | "outputs": [], 322 | "source": [ 323 | "s = P.tikz([-0.9555,0.2453,0.1639],114.89, output_type='LatexExpr')\n", 324 | "TikzPicture(s)" 325 | ] 326 | }, 327 | { 328 | "cell_type": "code", 329 | "execution_count": null, 330 | "id": "2b6aa655", 331 | "metadata": {}, 332 | "outputs": [], 333 | "source": [ 334 | "P.tikz([674,108,-731],112, output_type='TikzPicture')" 335 | ] 336 | }, 337 | { 338 | "cell_type": "markdown", 339 | "id": "62a4c913", 340 | "metadata": { 341 | "slideshow": { 342 | "slide_type": "subslide" 343 | } 344 | }, 345 | "source": [ 346 | "## Graphs" 347 | ] 348 | }, 349 | { 350 | "cell_type": "code", 351 | "execution_count": null, 352 | "id": "ff81445f", 353 | "metadata": {}, 354 | "outputs": [], 355 | "source": [ 356 | "g = graphs.PetersenGraph()\n", 357 | "t = TikzPicture(latex(g), usepackage=['tkz-graph'])\n", 358 | "t" 359 | ] 360 | }, 361 | { 362 | "cell_type": "markdown", 363 | "id": "58283960", 364 | "metadata": { 365 | "slideshow": { 366 | "slide_type": "subslide" 367 | } 368 | }, 369 | "source": [ 370 | "## TikzPicture.from_graph\n", 371 | "\n", 372 | "Using dot2tex and graphviz:\n", 373 | "\n", 374 | " - `sudo apt install graphviz`\n", 375 | " - `sage -pip install dot2tex` or `sage -i dot2tex`" 376 | ] 377 | }, 378 | { 379 | "cell_type": "code", 380 | "execution_count": null, 381 | "id": "e258e11c", 382 | "metadata": {}, 383 | "outputs": [], 384 | "source": [ 385 | "F = GF(3)\n", 386 | "gens = [matrix(F,2,[1,0, 1,1]), matrix(F,2, [1,1, 0,1])]\n", 387 | "group = MatrixGroup(gens); group" 388 | ] 389 | }, 390 | { 391 | "cell_type": "code", 392 | "execution_count": null, 393 | "id": "aff7bcb4", 394 | "metadata": {}, 395 | "outputs": [], 396 | "source": [ 397 | "group.cardinality()" 398 | ] 399 | }, 400 | { 401 | "cell_type": "code", 402 | "execution_count": null, 403 | "id": "4d711f18", 404 | "metadata": {}, 405 | "outputs": [], 406 | "source": [ 407 | "G = group.cayley_graph()\n", 408 | "G" 409 | ] 410 | }, 411 | { 412 | "cell_type": "code", 413 | "execution_count": null, 414 | "id": "49b49831", 415 | "metadata": {}, 416 | "outputs": [], 417 | "source": [ 418 | "G.plot()" 419 | ] 420 | }, 421 | { 422 | "cell_type": "code", 423 | "execution_count": null, 424 | "id": "95bc8ea2", 425 | "metadata": {}, 426 | "outputs": [], 427 | "source": [ 428 | "TikzPicture.from_graph(G, prog='fdp', color_by_label=True)" 429 | ] 430 | }, 431 | { 432 | "cell_type": "markdown", 433 | "id": "30220122", 434 | "metadata": {}, 435 | "source": [ 436 | "## Save to files" 437 | ] 438 | }, 439 | { 440 | "cell_type": "code", 441 | "execution_count": null, 442 | "id": "3423392c", 443 | "metadata": {}, 444 | "outputs": [], 445 | "source": [ 446 | "print(t)" 447 | ] 448 | }, 449 | { 450 | "cell_type": "code", 451 | "execution_count": null, 452 | "id": "ee90b2ad", 453 | "metadata": {}, 454 | "outputs": [], 455 | "source": [ 456 | "t.pdf('local_file.pdf')" 457 | ] 458 | }, 459 | { 460 | "cell_type": "code", 461 | "execution_count": null, 462 | "id": "fc3f4304", 463 | "metadata": {}, 464 | "outputs": [], 465 | "source": [ 466 | "t.png('local_file.png')" 467 | ] 468 | }, 469 | { 470 | "cell_type": "code", 471 | "execution_count": null, 472 | "id": "895d5f6e", 473 | "metadata": {}, 474 | "outputs": [], 475 | "source": [ 476 | "t.svg('local_file.svg')" 477 | ] 478 | }, 479 | { 480 | "cell_type": "code", 481 | "execution_count": null, 482 | "id": "a1d177b5", 483 | "metadata": {}, 484 | "outputs": [], 485 | "source": [ 486 | "t.tex('local_file.tex')" 487 | ] 488 | }, 489 | { 490 | "cell_type": "code", 491 | "execution_count": null, 492 | "id": "04fb4ae1", 493 | "metadata": {}, 494 | "outputs": [], 495 | "source": [ 496 | "t.tex('local_file.tex', content_only=True)" 497 | ] 498 | }, 499 | { 500 | "cell_type": "markdown", 501 | "id": "9271eb07", 502 | "metadata": { 503 | "slideshow": { 504 | "slide_type": "slide" 505 | } 506 | }, 507 | "source": [ 508 | "# 5. `RecursivelyEnumeratedSet` in SageMath" 509 | ] 510 | }, 511 | { 512 | "cell_type": "markdown", 513 | "id": "8d7a28c6", 514 | "metadata": {}, 515 | "source": [ 516 | "## First example" 517 | ] 518 | }, 519 | { 520 | "cell_type": "code", 521 | "execution_count": null, 522 | "id": "dabba278", 523 | "metadata": {}, 524 | "outputs": [], 525 | "source": [ 526 | "from slabbe.bispecial_extension_type import ExtensionTypeLong\n", 527 | "from slabbe.mult_cont_frac import Brun\n", 528 | "S = Brun().substitutions()\n", 529 | "data = [((2, 1), (2,)), ((3, 1), (2,)), ((2, 2), (3,)), \n", 530 | " ((1,2), (1,)), ((1, 2), (2,)), ((1, 2), (3,)), ((2, 3), (1,))]\n", 531 | "E1 = ExtensionTypeLong(data, (1,2,3))\n", 532 | "E1" 533 | ] 534 | }, 535 | { 536 | "cell_type": "code", 537 | "execution_count": null, 538 | "id": "7460f7cb", 539 | "metadata": {}, 540 | "outputs": [], 541 | "source": [ 542 | "latex(E1)" 543 | ] 544 | }, 545 | { 546 | "cell_type": "code", 547 | "execution_count": null, 548 | "id": "b8c0891f", 549 | "metadata": {}, 550 | "outputs": [], 551 | "source": [ 552 | "G = E1.graph_under_sadic([132]*2+[123]*6, S)\n", 553 | "G" 554 | ] 555 | }, 556 | { 557 | "cell_type": "code", 558 | "execution_count": null, 559 | "id": "4535d6bf", 560 | "metadata": {}, 561 | "outputs": [], 562 | "source": [ 563 | "TikzPicture.from_graph(G)" 564 | ] 565 | }, 566 | { 567 | "cell_type": "code", 568 | "execution_count": null, 569 | "id": "d367bed8", 570 | "metadata": {}, 571 | "outputs": [], 572 | "source": [ 573 | "E1.graph_under_sadic??" 574 | ] 575 | }, 576 | { 577 | "cell_type": "code", 578 | "execution_count": null, 579 | "id": "54869074", 580 | "metadata": {}, 581 | "outputs": [], 582 | "source": [ 583 | "E1.rec_enum_set_under_sadic??" 584 | ] 585 | }, 586 | { 587 | "cell_type": "markdown", 588 | "id": "555a3785", 589 | "metadata": { 590 | "slideshow": { 591 | "slide_type": "subslide" 592 | } 593 | }, 594 | "source": [ 595 | "## Baby example" 596 | ] 597 | }, 598 | { 599 | "cell_type": "code", 600 | "execution_count": null, 601 | "id": "e018c275", 602 | "metadata": { 603 | "slideshow": { 604 | "slide_type": "-" 605 | } 606 | }, 607 | "outputs": [], 608 | "source": [ 609 | "RecursivelyEnumeratedSet?" 610 | ] 611 | }, 612 | { 613 | "cell_type": "code", 614 | "execution_count": null, 615 | "id": "a79407ea", 616 | "metadata": {}, 617 | "outputs": [], 618 | "source": [ 619 | "f = lambda a: [2*a,2*a+1]\n", 620 | "C = RecursivelyEnumeratedSet([1], f, structure='forest')\n", 621 | "C" 622 | ] 623 | }, 624 | { 625 | "cell_type": "code", 626 | "execution_count": null, 627 | "id": "199a75ba", 628 | "metadata": {}, 629 | "outputs": [], 630 | "source": [ 631 | "it = C.depth_first_search_iterator()\n", 632 | "[next(it) for _ in range(7)]" 633 | ] 634 | }, 635 | { 636 | "cell_type": "code", 637 | "execution_count": null, 638 | "id": "c2504370", 639 | "metadata": {}, 640 | "outputs": [], 641 | "source": [ 642 | "it = C.breadth_first_search_iterator()\n", 643 | "[next(it) for _ in range(7)]" 644 | ] 645 | }, 646 | { 647 | "cell_type": "code", 648 | "execution_count": null, 649 | "id": "a794dcce", 650 | "metadata": {}, 651 | "outputs": [], 652 | "source": [ 653 | "C = RecursivelyEnumeratedSet([1], f)" 654 | ] 655 | }, 656 | { 657 | "cell_type": "code", 658 | "execution_count": null, 659 | "id": "3e1b4069", 660 | "metadata": {}, 661 | "outputs": [], 662 | "source": [ 663 | "G = C.to_digraph(max_depth=4)\n", 664 | "G" 665 | ] 666 | }, 667 | { 668 | "cell_type": "code", 669 | "execution_count": null, 670 | "id": "3af3acb3", 671 | "metadata": {}, 672 | "outputs": [], 673 | "source": [ 674 | "G.plot()" 675 | ] 676 | }, 677 | { 678 | "cell_type": "code", 679 | "execution_count": null, 680 | "id": "3d8477e6", 681 | "metadata": {}, 682 | "outputs": [], 683 | "source": [ 684 | "TikzPicture.from_graph(G)" 685 | ] 686 | }, 687 | { 688 | "cell_type": "markdown", 689 | "id": "75041e5c", 690 | "metadata": {}, 691 | "source": [ 692 | "# Parallel computations using RecursivelyEnumeratedSet and Map-Reduce\n", 693 | "\n", 694 | "When `structure='forest'`\n", 695 | "\n", 696 | "https://doc.sagemath.org/html/en/reference/parallel/sage/parallel/map_reduce.html" 697 | ] 698 | }, 699 | { 700 | "cell_type": "markdown", 701 | "id": "2a810aca", 702 | "metadata": {}, 703 | "source": [ 704 | "Counting the number of elements. In this situation, the map function can be set to `lambda x: 1`, and the reduce function just adds the values together, i.e. `lambda x, y: x + y`.\n", 705 | "\n", 706 | "We count binary words of length <= 16:" 707 | ] 708 | }, 709 | { 710 | "cell_type": "code", 711 | "execution_count": null, 712 | "id": "8ae0d0e4", 713 | "metadata": {}, 714 | "outputs": [], 715 | "source": [ 716 | "seeds = [[]]\n", 717 | "succ = lambda l: [l + [0], l + [1]] if len(l) < 16 else []\n", 718 | "S = RecursivelyEnumeratedSet(seeds, succ,\n", 719 | " structure='forest', enumeration='depth')\n", 720 | "map_function = lambda x: 1\n", 721 | "reduce_function = lambda x, y: x + y\n", 722 | "reduce_init = 0\n", 723 | "S.map_reduce(map_function, reduce_function, reduce_init)" 724 | ] 725 | }, 726 | { 727 | "cell_type": "code", 728 | "execution_count": null, 729 | "id": "87db7c33", 730 | "metadata": {}, 731 | "outputs": [], 732 | "source": [ 733 | "2^17" 734 | ] 735 | }, 736 | { 737 | "cell_type": "code", 738 | "execution_count": null, 739 | "id": "2caa3c6d", 740 | "metadata": {}, 741 | "outputs": [], 742 | "source": [] 743 | } 744 | ], 745 | "metadata": { 746 | "celltoolbar": "Diaporama", 747 | "kernelspec": { 748 | "display_name": "SageMath 9.8.beta1", 749 | "language": "sage", 750 | "name": "sagemath" 751 | }, 752 | "language_info": { 753 | "codemirror_mode": { 754 | "name": "ipython", 755 | "version": 3 756 | }, 757 | "file_extension": ".py", 758 | "mimetype": "text/x-python", 759 | "name": "python", 760 | "nbconvert_exporter": "python", 761 | "pygments_lexer": "ipython3", 762 | "version": "3.8.10" 763 | } 764 | }, 765 | "nbformat": 4, 766 | "nbformat_minor": 5 767 | } 768 | -------------------------------------------------------------------------------- /resources/SageMath-tutorials/tour_linalg.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "0d3c3be7", 6 | "metadata": {}, 7 | "source": [ 8 | "$$\n", 9 | "\\def\\CC{\\bf C}\n", 10 | "\\def\\QQ{\\bf Q}\n", 11 | "\\def\\RR{\\bf R}\n", 12 | "\\def\\ZZ{\\bf Z}\n", 13 | "\\def\\NN{\\bf N}\n", 14 | "$$\n", 15 | "# Linear Algebra\n", 16 | "\n", 17 | "Sage provides standard constructions from linear algebra, e.g., the\n", 18 | "characteristic polynomial, echelon form, trace, decomposition, etc., of\n", 19 | "a matrix.\n", 20 | "\n", 21 | "Creation of matrices and matrix multiplication is easy and natural:" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": null, 27 | "id": "0397546b", 28 | "metadata": {}, 29 | "outputs": [ 30 | { 31 | "data": { 32 | "text/plain": [ 33 | "(0, 0, 0)" 34 | ] 35 | }, 36 | "execution_count": 1, 37 | "metadata": {}, 38 | "output_type": "execute_result" 39 | } 40 | ], 41 | "source": [ 42 | "A = Matrix([[1,2,3],[3,2,1],[1,1,1]])\n", 43 | "w = vector([1,1,-4])\n", 44 | "w*A" 45 | ] 46 | }, 47 | { 48 | "cell_type": "code", 49 | "execution_count": null, 50 | "id": "534428af", 51 | "metadata": {}, 52 | "outputs": [ 53 | { 54 | "data": { 55 | "text/plain": [ 56 | "(-9, 1, -2)" 57 | ] 58 | }, 59 | "execution_count": 1, 60 | "metadata": {}, 61 | "output_type": "execute_result" 62 | } 63 | ], 64 | "source": [ 65 | "A*w" 66 | ] 67 | }, 68 | { 69 | "cell_type": "code", 70 | "execution_count": null, 71 | "id": "95f084e6", 72 | "metadata": {}, 73 | "outputs": [ 74 | { 75 | "data": { 76 | "text/plain": [ 77 | "Free module of degree 3 and rank 1 over Integer Ring\n", 78 | "Echelon basis matrix:\n", 79 | "[ 1 1 -4]" 80 | ] 81 | }, 82 | "execution_count": 1, 83 | "metadata": {}, 84 | "output_type": "execute_result" 85 | } 86 | ], 87 | "source": [ 88 | "kernel(A)" 89 | ] 90 | }, 91 | { 92 | "cell_type": "markdown", 93 | "id": "2e8f8eb5", 94 | "metadata": {}, 95 | "source": [ 96 | "Note that in Sage, the kernel of a matrix $A$ is the \"left kernel\", i.e.\n", 97 | "the space of vectors $w$ such that $wA=0$.\n", 98 | "\n", 99 | "Solving matrix equations is easy, using the method `solve_right`.\n", 100 | "Evaluating `A.solve_right(Y)` returns a matrix (or vector) $X$ so that\n", 101 | "$AX=Y$ :" 102 | ] 103 | }, 104 | { 105 | "cell_type": "code", 106 | "execution_count": null, 107 | "id": "856eb2c5", 108 | "metadata": {}, 109 | "outputs": [ 110 | { 111 | "data": { 112 | "text/plain": [ 113 | "(-2, 1, 0)" 114 | ] 115 | }, 116 | "execution_count": 1, 117 | "metadata": {}, 118 | "output_type": "execute_result" 119 | } 120 | ], 121 | "source": [ 122 | "Y = vector([0, -4, -1])\n", 123 | "X = A.solve_right(Y)\n", 124 | "X" 125 | ] 126 | }, 127 | { 128 | "cell_type": "code", 129 | "execution_count": null, 130 | "id": "6e226129", 131 | "metadata": {}, 132 | "outputs": [ 133 | { 134 | "data": { 135 | "text/plain": [ 136 | "(0, -4, -1)" 137 | ] 138 | }, 139 | "execution_count": 1, 140 | "metadata": {}, 141 | "output_type": "execute_result" 142 | } 143 | ], 144 | "source": [ 145 | "A * X # checking our answer..." 146 | ] 147 | }, 148 | { 149 | "cell_type": "markdown", 150 | "id": "c10e8760", 151 | "metadata": {}, 152 | "source": [ 153 | "A backslash `\\` can be used in the place of `solve_right`; use `A \\ Y`\n", 154 | "instead of `A.solve_right(Y)`." 155 | ] 156 | }, 157 | { 158 | "cell_type": "code", 159 | "execution_count": null, 160 | "id": "9d8692bd", 161 | "metadata": {}, 162 | "outputs": [ 163 | { 164 | "data": { 165 | "text/plain": [ 166 | "(-2, 1, 0)" 167 | ] 168 | }, 169 | "execution_count": 1, 170 | "metadata": {}, 171 | "output_type": "execute_result" 172 | } 173 | ], 174 | "source": [ 175 | "A \\ Y" 176 | ] 177 | }, 178 | { 179 | "cell_type": "markdown", 180 | "id": "9f184833", 181 | "metadata": {}, 182 | "source": [ 183 | "If there is no solution, Sage returns an error:" 184 | ] 185 | }, 186 | { 187 | "cell_type": "code", 188 | "execution_count": null, 189 | "id": "4d1b8d34", 190 | "metadata": {}, 191 | "outputs": [ 192 | { 193 | "data": { 194 | "text/plain": [ 195 | "Traceback (most recent call last):\n", 196 | "...\n", 197 | "ValueError: matrix equation has no solutions" 198 | ] 199 | }, 200 | "execution_count": 1, 201 | "metadata": {}, 202 | "output_type": "execute_result" 203 | } 204 | ], 205 | "source": [ 206 | "A.solve_right(w)" 207 | ] 208 | }, 209 | { 210 | "cell_type": "markdown", 211 | "id": "fdd500cb", 212 | "metadata": {}, 213 | "source": [ 214 | "Similarly, use `A.solve_left(Y)` to solve for $X$ in $XA=Y$.\n", 215 | "\n", 216 | "Sage can also compute eigenvalues and eigenvectors:" 217 | ] 218 | }, 219 | { 220 | "cell_type": "code", 221 | "execution_count": null, 222 | "id": "cffa07a9", 223 | "metadata": {}, 224 | "outputs": [ 225 | { 226 | "data": { 227 | "text/plain": [ 228 | "[-2*I, 2*I]" 229 | ] 230 | }, 231 | "execution_count": 1, 232 | "metadata": {}, 233 | "output_type": "execute_result" 234 | } 235 | ], 236 | "source": [ 237 | "A = matrix([[0, 4], [-1, 0]])\n", 238 | "A.eigenvalues ()" 239 | ] 240 | }, 241 | { 242 | "cell_type": "code", 243 | "execution_count": null, 244 | "id": "b1069301", 245 | "metadata": {}, 246 | "outputs": [ 247 | { 248 | "data": { 249 | "text/plain": [ 250 | "[(4, [\n", 251 | "(1, 1)\n", 252 | "], 1), (-2, [\n", 253 | "(1, -1)\n", 254 | "], 1)]" 255 | ] 256 | }, 257 | "execution_count": 1, 258 | "metadata": {}, 259 | "output_type": "execute_result" 260 | } 261 | ], 262 | "source": [ 263 | "B = matrix([[1, 3], [3, 1]])\n", 264 | "B.eigenvectors_left()" 265 | ] 266 | }, 267 | { 268 | "cell_type": "markdown", 269 | "id": "0cd314be", 270 | "metadata": {}, 271 | "source": [ 272 | "(The syntax for the output of `eigenvectors_left` is a list of triples:\n", 273 | "(eigenvalue, eigenvector, multiplicity).) Eigenvalues and eigenvectors\n", 274 | "over `QQ` or `RR` can also be computed using Maxima (see\n", 275 | "[section-maxima](section-maxima.ipynb) below).\n", 276 | "\n", 277 | "As noted in [section-rings](section-rings.ipynb), the ring over which a\n", 278 | "matrix is defined affects some of its properties. In the following, the\n", 279 | "first argument to the `matrix` command tells Sage to view the matrix as\n", 280 | "a matrix of integers (the `ZZ` case), a matrix of rational numbers\n", 281 | "(`QQ`), or a matrix of reals (`RR`):" 282 | ] 283 | }, 284 | { 285 | "cell_type": "code", 286 | "execution_count": null, 287 | "id": "e2c0d5c8", 288 | "metadata": {}, 289 | "outputs": [ 290 | { 291 | "data": { 292 | "text/plain": [ 293 | "[2 0]\n", 294 | "[0 1]" 295 | ] 296 | }, 297 | "execution_count": 1, 298 | "metadata": {}, 299 | "output_type": "execute_result" 300 | } 301 | ], 302 | "source": [ 303 | "AZ = matrix(ZZ, [[2,0], [0,1]])\n", 304 | "AQ = matrix(QQ, [[2,0], [0,1]])\n", 305 | "AR = matrix(RR, [[2,0], [0,1]])\n", 306 | "AZ.echelon_form()" 307 | ] 308 | }, 309 | { 310 | "cell_type": "code", 311 | "execution_count": null, 312 | "id": "6ccd7383", 313 | "metadata": {}, 314 | "outputs": [ 315 | { 316 | "data": { 317 | "text/plain": [ 318 | "[1 0]\n", 319 | "[0 1]" 320 | ] 321 | }, 322 | "execution_count": 1, 323 | "metadata": {}, 324 | "output_type": "execute_result" 325 | } 326 | ], 327 | "source": [ 328 | "AQ.echelon_form()" 329 | ] 330 | }, 331 | { 332 | "cell_type": "code", 333 | "execution_count": null, 334 | "id": "45560f35", 335 | "metadata": {}, 336 | "outputs": [ 337 | { 338 | "data": { 339 | "text/plain": [ 340 | "[ 1.00000000000000 0.000000000000000]\n", 341 | "[0.000000000000000 1.00000000000000]" 342 | ] 343 | }, 344 | "execution_count": 1, 345 | "metadata": {}, 346 | "output_type": "execute_result" 347 | } 348 | ], 349 | "source": [ 350 | "AR.echelon_form()" 351 | ] 352 | }, 353 | { 354 | "cell_type": "markdown", 355 | "id": "b4a0301f", 356 | "metadata": {}, 357 | "source": [ 358 | "For computing eigenvalues and eigenvectors of matrices over floating\n", 359 | "point real or complex numbers, the matrix should be defined over `RDF`\n", 360 | "(Real Double Field) or `CDF` (Complex Double Field), respectively. If no\n", 361 | "ring is specified and floating point real or complex numbers are used\n", 362 | "then by default the matrix is defined over the `RR` or `CC` fields,\n", 363 | "respectively, which do not support these computations for all the cases:" 364 | ] 365 | }, 366 | { 367 | "cell_type": "code", 368 | "execution_count": null, 369 | "id": "21755720", 370 | "metadata": {}, 371 | "outputs": [ 372 | { 373 | "data": { 374 | "text/plain": [ 375 | "[-0.09317121994613098, 4.293171219946131]" 376 | ] 377 | }, 378 | "execution_count": 1, 379 | "metadata": {}, 380 | "output_type": "execute_result" 381 | } 382 | ], 383 | "source": [ 384 | "ARDF = matrix(RDF, [[1.2, 2], [2, 3]])\n", 385 | "ARDF.eigenvalues() # rel tol 8e-16" 386 | ] 387 | }, 388 | { 389 | "cell_type": "code", 390 | "execution_count": null, 391 | "id": "af28ce0f", 392 | "metadata": {}, 393 | "outputs": [ 394 | { 395 | "data": { 396 | "text/plain": [ 397 | "[(0.8818456983293743 - 0.8209140653434135*I, [(0.7505608183809549, -0.616145932704589 + 0.2387941530333261*I)], 1),\n", 398 | "(3.3181543016706256 + 0.8209140653434133*I, [(0.14559469829270957 + 0.3756690858502104*I, 0.9152458258662108)], 1)]" 399 | ] 400 | }, 401 | "execution_count": 1, 402 | "metadata": {}, 403 | "output_type": "execute_result" 404 | } 405 | ], 406 | "source": [ 407 | "ACDF = matrix(CDF, [[1.2, I], [2, 3]])\n", 408 | "ACDF.eigenvectors_right() # rel tol 3e-15" 409 | ] 410 | }, 411 | { 412 | "cell_type": "markdown", 413 | "id": "5222a9a1", 414 | "metadata": {}, 415 | "source": [ 416 | "## Matrix spaces\n", 417 | "\n", 418 | "We create the space $\\text{Mat}_{3\\times 3}(\\QQ)$ of $3 \\times\n", 419 | "3$ matrices with rational entries:" 420 | ] 421 | }, 422 | { 423 | "cell_type": "code", 424 | "execution_count": null, 425 | "id": "331d007b", 426 | "metadata": {}, 427 | "outputs": [ 428 | { 429 | "data": { 430 | "text/plain": [ 431 | "Full MatrixSpace of 3 by 3 dense matrices over Rational Field" 432 | ] 433 | }, 434 | "execution_count": 1, 435 | "metadata": {}, 436 | "output_type": "execute_result" 437 | } 438 | ], 439 | "source": [ 440 | "M = MatrixSpace(QQ,3)\n", 441 | "M" 442 | ] 443 | }, 444 | { 445 | "cell_type": "markdown", 446 | "id": "ac03805e", 447 | "metadata": {}, 448 | "source": [ 449 | "(To specify the space of 3 by 4 matrices, you would use\n", 450 | "`MatrixSpace(QQ,3,4)`. If the number of columns is omitted, it defaults\n", 451 | "to the number of rows, so `MatrixSpace(QQ,3)` is a synonym for\n", 452 | "`MatrixSpace(QQ,3,3)`.) The space of matrices is equipped with its\n", 453 | "canonical basis:" 454 | ] 455 | }, 456 | { 457 | "cell_type": "code", 458 | "execution_count": null, 459 | "id": "d7bab6a4", 460 | "metadata": {}, 461 | "outputs": [ 462 | { 463 | "data": { 464 | "text/plain": [ 465 | "9" 466 | ] 467 | }, 468 | "execution_count": 1, 469 | "metadata": {}, 470 | "output_type": "execute_result" 471 | } 472 | ], 473 | "source": [ 474 | "B = M.basis()\n", 475 | "len(B)" 476 | ] 477 | }, 478 | { 479 | "cell_type": "code", 480 | "execution_count": null, 481 | "id": "3f4ec77b", 482 | "metadata": {}, 483 | "outputs": [ 484 | { 485 | "data": { 486 | "text/plain": [ 487 | "[0 1 0]\n", 488 | "[0 0 0]\n", 489 | "[0 0 0]" 490 | ] 491 | }, 492 | "execution_count": 1, 493 | "metadata": {}, 494 | "output_type": "execute_result" 495 | } 496 | ], 497 | "source": [ 498 | "B[0,1]" 499 | ] 500 | }, 501 | { 502 | "cell_type": "markdown", 503 | "id": "740750b9", 504 | "metadata": {}, 505 | "source": [ 506 | "We create a matrix as an element of `M`." 507 | ] 508 | }, 509 | { 510 | "cell_type": "code", 511 | "execution_count": null, 512 | "id": "52d05f8e", 513 | "metadata": {}, 514 | "outputs": [ 515 | { 516 | "data": { 517 | "text/plain": [ 518 | "[0 1 2]\n", 519 | "[3 4 5]\n", 520 | "[6 7 8]" 521 | ] 522 | }, 523 | "execution_count": 1, 524 | "metadata": {}, 525 | "output_type": "execute_result" 526 | } 527 | ], 528 | "source": [ 529 | "A = M(range(9)); A" 530 | ] 531 | }, 532 | { 533 | "cell_type": "markdown", 534 | "id": "b02acdb0", 535 | "metadata": {}, 536 | "source": [ 537 | "Next we compute its reduced row echelon form and kernel." 538 | ] 539 | }, 540 | { 541 | "cell_type": "code", 542 | "execution_count": null, 543 | "id": "b885cb7b", 544 | "metadata": {}, 545 | "outputs": [ 546 | { 547 | "data": { 548 | "text/plain": [ 549 | "[ 1 0 -1]\n", 550 | "[ 0 1 2]\n", 551 | "[ 0 0 0]" 552 | ] 553 | }, 554 | "execution_count": 1, 555 | "metadata": {}, 556 | "output_type": "execute_result" 557 | } 558 | ], 559 | "source": [ 560 | "A.echelon_form()" 561 | ] 562 | }, 563 | { 564 | "cell_type": "code", 565 | "execution_count": null, 566 | "id": "d64b6f93", 567 | "metadata": {}, 568 | "outputs": [ 569 | { 570 | "data": { 571 | "text/plain": [ 572 | "Vector space of degree 3 and dimension 1 over Rational Field\n", 573 | "Basis matrix:\n", 574 | "[ 1 -2 1]" 575 | ] 576 | }, 577 | "execution_count": 1, 578 | "metadata": {}, 579 | "output_type": "execute_result" 580 | } 581 | ], 582 | "source": [ 583 | "A.kernel()" 584 | ] 585 | }, 586 | { 587 | "cell_type": "markdown", 588 | "id": "eb55c58e", 589 | "metadata": {}, 590 | "source": [ 591 | "Next we illustrate computation of matrices defined over finite fields:" 592 | ] 593 | }, 594 | { 595 | "cell_type": "code", 596 | "execution_count": null, 597 | "id": "1e564f27", 598 | "metadata": {}, 599 | "outputs": [ 600 | { 601 | "data": { 602 | "text/plain": [ 603 | "[1 1 0 0 1 1 1 1]\n", 604 | "[0 1 0 0 1 0 1 1]\n", 605 | "[0 0 1 0 1 1 0 1]\n", 606 | "[0 0 1 1 1 1 1 0]" 607 | ] 608 | }, 609 | "execution_count": 1, 610 | "metadata": {}, 611 | "output_type": "execute_result" 612 | } 613 | ], 614 | "source": [ 615 | "M = MatrixSpace(GF(2),4,8)\n", 616 | "A = M([1,1,0,0, 1,1,1,1, 0,1,0,0, 1,0,1,1,\n", 617 | " 0,0,1,0, 1,1,0,1, 0,0,1,1, 1,1,1,0])\n", 618 | "A" 619 | ] 620 | }, 621 | { 622 | "cell_type": "code", 623 | "execution_count": null, 624 | "id": "595cabb9", 625 | "metadata": {}, 626 | "outputs": [ 627 | { 628 | "data": { 629 | "text/plain": [ 630 | "[(1, 0, 0, 0), (1, 1, 0, 0), (0, 0, 1, 1), (0, 0, 0, 1),\n", 631 | " (1, 1, 1, 1), (1, 0, 1, 1), (1, 1, 0, 1), (1, 1, 1, 0)]" 632 | ] 633 | }, 634 | "execution_count": 1, 635 | "metadata": {}, 636 | "output_type": "execute_result" 637 | } 638 | ], 639 | "source": [ 640 | "rows = A.rows()\n", 641 | "A.columns()" 642 | ] 643 | }, 644 | { 645 | "cell_type": "code", 646 | "execution_count": null, 647 | "id": "af257491", 648 | "metadata": {}, 649 | "outputs": [ 650 | { 651 | "data": { 652 | "text/plain": [ 653 | "[(1, 1, 0, 0, 1, 1, 1, 1), (0, 1, 0, 0, 1, 0, 1, 1),\n", 654 | " (0, 0, 1, 0, 1, 1, 0, 1), (0, 0, 1, 1, 1, 1, 1, 0)]" 655 | ] 656 | }, 657 | "execution_count": 1, 658 | "metadata": {}, 659 | "output_type": "execute_result" 660 | } 661 | ], 662 | "source": [ 663 | "rows" 664 | ] 665 | }, 666 | { 667 | "cell_type": "markdown", 668 | "id": "e4164b5c", 669 | "metadata": {}, 670 | "source": [ 671 | "We make the subspace over $\\GF{2}$ spanned by the above rows." 672 | ] 673 | }, 674 | { 675 | "cell_type": "code", 676 | "execution_count": null, 677 | "id": "80b7805a", 678 | "metadata": {}, 679 | "outputs": [ 680 | { 681 | "data": { 682 | "text/plain": [ 683 | "Vector space of degree 8 and dimension 4 over Finite Field of size 2\n", 684 | "Basis matrix:\n", 685 | "[1 0 0 0 0 1 0 0]\n", 686 | "[0 1 0 0 1 0 1 1]\n", 687 | "[0 0 1 0 1 1 0 1]\n", 688 | "[0 0 0 1 0 0 1 1]" 689 | ] 690 | }, 691 | "execution_count": 1, 692 | "metadata": {}, 693 | "output_type": "execute_result" 694 | } 695 | ], 696 | "source": [ 697 | "V = VectorSpace(GF(2),8)\n", 698 | "S = V.subspace(rows)\n", 699 | "S" 700 | ] 701 | }, 702 | { 703 | "cell_type": "code", 704 | "execution_count": null, 705 | "id": "4b5b8022", 706 | "metadata": {}, 707 | "outputs": [ 708 | { 709 | "data": { 710 | "text/plain": [ 711 | "[1 0 0 0 0 1 0 0]\n", 712 | "[0 1 0 0 1 0 1 1]\n", 713 | "[0 0 1 0 1 1 0 1]\n", 714 | "[0 0 0 1 0 0 1 1]" 715 | ] 716 | }, 717 | "execution_count": 1, 718 | "metadata": {}, 719 | "output_type": "execute_result" 720 | } 721 | ], 722 | "source": [ 723 | "A.echelon_form()" 724 | ] 725 | }, 726 | { 727 | "cell_type": "markdown", 728 | "id": "50f4084f", 729 | "metadata": {}, 730 | "source": [ 731 | "The basis of $S$ used by Sage is obtained from the non-zero rows of the\n", 732 | "reduced row echelon form of the matrix of generators of $S$.\n", 733 | "\n", 734 | "## Sparse Linear Algebra\n", 735 | "\n", 736 | "Sage has support for sparse linear algebra over PIDs." 737 | ] 738 | }, 739 | { 740 | "cell_type": "code", 741 | "execution_count": null, 742 | "id": "0819519d", 743 | "metadata": {}, 744 | "outputs": [], 745 | "source": [ 746 | "M = MatrixSpace(QQ, 100, sparse=True)\n", 747 | "A = M.random_element(density = 0.05)\n", 748 | "E = A.echelon_form()" 749 | ] 750 | }, 751 | { 752 | "cell_type": "markdown", 753 | "id": "2f411b73", 754 | "metadata": {}, 755 | "source": [ 756 | "The multi-modular algorithm in Sage is good for square matrices (but not\n", 757 | "so good for non-square matrices):" 758 | ] 759 | }, 760 | { 761 | "cell_type": "code", 762 | "execution_count": null, 763 | "id": "4c1c3e94", 764 | "metadata": {}, 765 | "outputs": [], 766 | "source": [ 767 | "M = MatrixSpace(QQ, 50, 100, sparse=True)\n", 768 | "A = M.random_element(density = 0.05)\n", 769 | "E = A.echelon_form()\n", 770 | "M = MatrixSpace(GF(2), 20, 40, sparse=True)\n", 771 | "A = M.random_element()\n", 772 | "E = A.echelon_form()" 773 | ] 774 | }, 775 | { 776 | "cell_type": "markdown", 777 | "id": "18e8d6a9", 778 | "metadata": {}, 779 | "source": [ 780 | "Note that Python is case sensitive:" 781 | ] 782 | }, 783 | { 784 | "cell_type": "code", 785 | "execution_count": null, 786 | "id": "c2dfcb21", 787 | "metadata": {}, 788 | "outputs": [ 789 | { 790 | "data": { 791 | "text/plain": [ 792 | "Traceback (most recent call last):\n", 793 | "...\n", 794 | "TypeError: ...__init__() got an unexpected keyword argument 'Sparse'" 795 | ] 796 | }, 797 | "execution_count": 1, 798 | "metadata": {}, 799 | "output_type": "execute_result" 800 | } 801 | ], 802 | "source": [ 803 | "M = MatrixSpace(QQ, 10,10, Sparse=True)" 804 | ] 805 | } 806 | ], 807 | "metadata": {}, 808 | "nbformat": 4, 809 | "nbformat_minor": 5 810 | } 811 | -------------------------------------------------------------------------------- /resources/SageMath-tutorials/tour_numtheory.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "2de7dddf", 6 | "metadata": {}, 7 | "source": [ 8 | "$$\n", 9 | "\\def\\CC{\\bf C}\n", 10 | "\\def\\QQ{\\bf Q}\n", 11 | "\\def\\RR{\\bf R}\n", 12 | "\\def\\ZZ{\\bf Z}\n", 13 | "\\def\\NN{\\bf N}\n", 14 | "$$\n", 15 | "# Number Theory\n", 16 | "\n", 17 | "Sage has extensive functionality for number theory. For example, we can\n", 18 | "do arithmetic in $\\ZZ/N\\ZZ$ as follows:" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": null, 24 | "id": "3296750b", 25 | "metadata": {}, 26 | "outputs": [ 27 | { 28 | "data": { 29 | "text/plain": [ 30 | "33" 31 | ] 32 | }, 33 | "execution_count": 1, 34 | "metadata": {}, 35 | "output_type": "execute_result" 36 | } 37 | ], 38 | "source": [ 39 | "R = IntegerModRing(97)\n", 40 | "a = R(2) / R(3)\n", 41 | "a" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": null, 47 | "id": "7e889e3e", 48 | "metadata": {}, 49 | "outputs": [ 50 | { 51 | "data": { 52 | "text/plain": [ 53 | "2/3" 54 | ] 55 | }, 56 | "execution_count": 1, 57 | "metadata": {}, 58 | "output_type": "execute_result" 59 | } 60 | ], 61 | "source": [ 62 | "a.rational_reconstruction()" 63 | ] 64 | }, 65 | { 66 | "cell_type": "code", 67 | "execution_count": null, 68 | "id": "956e4edd", 69 | "metadata": {}, 70 | "outputs": [ 71 | { 72 | "data": { 73 | "text/plain": [ 74 | "50" 75 | ] 76 | }, 77 | "execution_count": 1, 78 | "metadata": {}, 79 | "output_type": "execute_result" 80 | } 81 | ], 82 | "source": [ 83 | "b = R(47)\n", 84 | "b^20052005" 85 | ] 86 | }, 87 | { 88 | "cell_type": "code", 89 | "execution_count": null, 90 | "id": "fd10709d", 91 | "metadata": {}, 92 | "outputs": [ 93 | { 94 | "data": { 95 | "text/plain": [ 96 | "97" 97 | ] 98 | }, 99 | "execution_count": 1, 100 | "metadata": {}, 101 | "output_type": "execute_result" 102 | } 103 | ], 104 | "source": [ 105 | "b.modulus()" 106 | ] 107 | }, 108 | { 109 | "cell_type": "code", 110 | "execution_count": null, 111 | "id": "51053b0f", 112 | "metadata": {}, 113 | "outputs": [ 114 | { 115 | "data": { 116 | "text/plain": [ 117 | "True" 118 | ] 119 | }, 120 | "execution_count": 1, 121 | "metadata": {}, 122 | "output_type": "execute_result" 123 | } 124 | ], 125 | "source": [ 126 | "b.is_square()" 127 | ] 128 | }, 129 | { 130 | "cell_type": "markdown", 131 | "id": "88ab1c40", 132 | "metadata": {}, 133 | "source": [ 134 | "Sage contains standard number theoretic functions. For example," 135 | ] 136 | }, 137 | { 138 | "cell_type": "code", 139 | "execution_count": null, 140 | "id": "75ee7926", 141 | "metadata": {}, 142 | "outputs": [ 143 | { 144 | "data": { 145 | "text/plain": [ 146 | "5" 147 | ] 148 | }, 149 | "execution_count": 1, 150 | "metadata": {}, 151 | "output_type": "execute_result" 152 | } 153 | ], 154 | "source": [ 155 | "gcd(515,2005)" 156 | ] 157 | }, 158 | { 159 | "cell_type": "code", 160 | "execution_count": null, 161 | "id": "c8ed2434", 162 | "metadata": {}, 163 | "outputs": [ 164 | { 165 | "data": { 166 | "text/plain": [ 167 | "5 * 401" 168 | ] 169 | }, 170 | "execution_count": 1, 171 | "metadata": {}, 172 | "output_type": "execute_result" 173 | } 174 | ], 175 | "source": [ 176 | "factor(2005)" 177 | ] 178 | }, 179 | { 180 | "cell_type": "code", 181 | "execution_count": null, 182 | "id": "8f21c1ef", 183 | "metadata": {}, 184 | "outputs": [ 185 | { 186 | "data": { 187 | "text/plain": [ 188 | "15511210043330985984000000" 189 | ] 190 | }, 191 | "execution_count": 1, 192 | "metadata": {}, 193 | "output_type": "execute_result" 194 | } 195 | ], 196 | "source": [ 197 | "c = factorial(25); c" 198 | ] 199 | }, 200 | { 201 | "cell_type": "code", 202 | "execution_count": null, 203 | "id": "fc9f5f57", 204 | "metadata": {}, 205 | "outputs": [ 206 | { 207 | "data": { 208 | "text/plain": [ 209 | "[22, 10, 6, 3, 2, 1, 1, 1]" 210 | ] 211 | }, 212 | "execution_count": 1, 213 | "metadata": {}, 214 | "output_type": "execute_result" 215 | } 216 | ], 217 | "source": [ 218 | "[valuation(c,p) for p in prime_range(2,23)]" 219 | ] 220 | }, 221 | { 222 | "cell_type": "code", 223 | "execution_count": null, 224 | "id": "48763310", 225 | "metadata": {}, 226 | "outputs": [ 227 | { 228 | "data": { 229 | "text/plain": [ 230 | "2011" 231 | ] 232 | }, 233 | "execution_count": 1, 234 | "metadata": {}, 235 | "output_type": "execute_result" 236 | } 237 | ], 238 | "source": [ 239 | "next_prime(2005)" 240 | ] 241 | }, 242 | { 243 | "cell_type": "code", 244 | "execution_count": null, 245 | "id": "5eda6cf7", 246 | "metadata": {}, 247 | "outputs": [ 248 | { 249 | "data": { 250 | "text/plain": [ 251 | "2003" 252 | ] 253 | }, 254 | "execution_count": 1, 255 | "metadata": {}, 256 | "output_type": "execute_result" 257 | } 258 | ], 259 | "source": [ 260 | "previous_prime(2005)" 261 | ] 262 | }, 263 | { 264 | "cell_type": "code", 265 | "execution_count": null, 266 | "id": "282d63e5", 267 | "metadata": {}, 268 | "outputs": [ 269 | { 270 | "data": { 271 | "text/plain": [ 272 | "[1, 2, 4, 7, 14, 28]\n", 273 | "56\n", 274 | "56" 275 | ] 276 | }, 277 | "execution_count": 1, 278 | "metadata": {}, 279 | "output_type": "execute_result" 280 | } 281 | ], 282 | "source": [ 283 | "divisors(28); sum(divisors(28)); 2*28" 284 | ] 285 | }, 286 | { 287 | "cell_type": "markdown", 288 | "id": "ae93e6cd", 289 | "metadata": {}, 290 | "source": [ 291 | "Perfect!\n", 292 | "\n", 293 | "Sage's `sigma(n,k)` function adds up the $k^{th}$ powers of the divisors\n", 294 | "of `n` :" 295 | ] 296 | }, 297 | { 298 | "cell_type": "code", 299 | "execution_count": null, 300 | "id": "2b04338c", 301 | "metadata": {}, 302 | "outputs": [ 303 | { 304 | "data": { 305 | "text/plain": [ 306 | "6\n", 307 | "56\n", 308 | "1050" 309 | ] 310 | }, 311 | "execution_count": 1, 312 | "metadata": {}, 313 | "output_type": "execute_result" 314 | } 315 | ], 316 | "source": [ 317 | "sigma(28,0); sigma(28,1); sigma(28,2)" 318 | ] 319 | }, 320 | { 321 | "cell_type": "markdown", 322 | "id": "079b7f62", 323 | "metadata": {}, 324 | "source": [ 325 | "We next illustrate the extended Euclidean algorithm, Euler's\n", 326 | "$\\phi$-function, and the Chinese remainder theorem:" 327 | ] 328 | }, 329 | { 330 | "cell_type": "code", 331 | "execution_count": null, 332 | "id": "bb8bed35", 333 | "metadata": {}, 334 | "outputs": [ 335 | { 336 | "data": { 337 | "text/plain": [ 338 | "True" 339 | ] 340 | }, 341 | "execution_count": 1, 342 | "metadata": {}, 343 | "output_type": "execute_result" 344 | } 345 | ], 346 | "source": [ 347 | "d,u,v = xgcd(12,15)\n", 348 | "d == u*12 + v*15" 349 | ] 350 | }, 351 | { 352 | "cell_type": "code", 353 | "execution_count": null, 354 | "id": "b0a2b508", 355 | "metadata": {}, 356 | "outputs": [ 357 | { 358 | "data": { 359 | "text/plain": [ 360 | "1337" 361 | ] 362 | }, 363 | "execution_count": 1, 364 | "metadata": {}, 365 | "output_type": "execute_result" 366 | } 367 | ], 368 | "source": [ 369 | "n = 2005\n", 370 | "inverse_mod(3,n)" 371 | ] 372 | }, 373 | { 374 | "cell_type": "code", 375 | "execution_count": null, 376 | "id": "de0aeebe", 377 | "metadata": {}, 378 | "outputs": [ 379 | { 380 | "data": { 381 | "text/plain": [ 382 | "4011" 383 | ] 384 | }, 385 | "execution_count": 1, 386 | "metadata": {}, 387 | "output_type": "execute_result" 388 | } 389 | ], 390 | "source": [ 391 | "3 * 1337" 392 | ] 393 | }, 394 | { 395 | "cell_type": "code", 396 | "execution_count": null, 397 | "id": "d12033c5", 398 | "metadata": {}, 399 | "outputs": [ 400 | { 401 | "data": { 402 | "text/plain": [ 403 | "[5, 401]" 404 | ] 405 | }, 406 | "execution_count": 1, 407 | "metadata": {}, 408 | "output_type": "execute_result" 409 | } 410 | ], 411 | "source": [ 412 | "prime_divisors(n)" 413 | ] 414 | }, 415 | { 416 | "cell_type": "code", 417 | "execution_count": null, 418 | "id": "3b9864cd", 419 | "metadata": {}, 420 | "outputs": [ 421 | { 422 | "data": { 423 | "text/plain": [ 424 | "1600" 425 | ] 426 | }, 427 | "execution_count": 1, 428 | "metadata": {}, 429 | "output_type": "execute_result" 430 | } 431 | ], 432 | "source": [ 433 | "phi = n*prod([1 - 1/p for p in prime_divisors(n)]); phi" 434 | ] 435 | }, 436 | { 437 | "cell_type": "code", 438 | "execution_count": null, 439 | "id": "46984efd", 440 | "metadata": {}, 441 | "outputs": [ 442 | { 443 | "data": { 444 | "text/plain": [ 445 | "1600" 446 | ] 447 | }, 448 | "execution_count": 1, 449 | "metadata": {}, 450 | "output_type": "execute_result" 451 | } 452 | ], 453 | "source": [ 454 | "euler_phi(n)" 455 | ] 456 | }, 457 | { 458 | "cell_type": "code", 459 | "execution_count": null, 460 | "id": "ca1137e9", 461 | "metadata": {}, 462 | "outputs": [ 463 | { 464 | "data": { 465 | "text/plain": [ 466 | "401" 467 | ] 468 | }, 469 | "execution_count": 1, 470 | "metadata": {}, 471 | "output_type": "execute_result" 472 | } 473 | ], 474 | "source": [ 475 | "prime_to_m_part(n, 5)" 476 | ] 477 | }, 478 | { 479 | "cell_type": "markdown", 480 | "id": "479cba87", 481 | "metadata": {}, 482 | "source": [ 483 | "We next verify something about the $3n+1$ problem." 484 | ] 485 | }, 486 | { 487 | "cell_type": "code", 488 | "execution_count": null, 489 | "id": "74d28da5", 490 | "metadata": {}, 491 | "outputs": [ 492 | { 493 | "data": { 494 | "text/plain": [ 495 | "38" 496 | ] 497 | }, 498 | "execution_count": 1, 499 | "metadata": {}, 500 | "output_type": "execute_result" 501 | } 502 | ], 503 | "source": [ 504 | "n = 2005\n", 505 | "for i in range(1000):\n", 506 | " n = 3*odd_part(n) + 1\n", 507 | " if odd_part(n)==1:\n", 508 | " print(i)\n", 509 | " break" 510 | ] 511 | }, 512 | { 513 | "cell_type": "markdown", 514 | "id": "5801d599", 515 | "metadata": {}, 516 | "source": [ 517 | "Finally we illustrate the Chinese remainder theorem." 518 | ] 519 | }, 520 | { 521 | "cell_type": "code", 522 | "execution_count": null, 523 | "id": "eacfb9b0", 524 | "metadata": {}, 525 | "outputs": [ 526 | { 527 | "data": { 528 | "text/plain": [ 529 | "11" 530 | ] 531 | }, 532 | "execution_count": 1, 533 | "metadata": {}, 534 | "output_type": "execute_result" 535 | } 536 | ], 537 | "source": [ 538 | "x = crt(2, 1, 3, 5); x" 539 | ] 540 | }, 541 | { 542 | "cell_type": "code", 543 | "execution_count": null, 544 | "id": "ec71ae54", 545 | "metadata": {}, 546 | "outputs": [ 547 | { 548 | "data": { 549 | "text/plain": [ 550 | "2" 551 | ] 552 | }, 553 | "execution_count": 1, 554 | "metadata": {}, 555 | "output_type": "execute_result" 556 | } 557 | ], 558 | "source": [ 559 | "x % 3 # x mod 3 = 2" 560 | ] 561 | }, 562 | { 563 | "cell_type": "code", 564 | "execution_count": null, 565 | "id": "26904542", 566 | "metadata": {}, 567 | "outputs": [ 568 | { 569 | "data": { 570 | "text/plain": [ 571 | "1" 572 | ] 573 | }, 574 | "execution_count": 1, 575 | "metadata": {}, 576 | "output_type": "execute_result" 577 | } 578 | ], 579 | "source": [ 580 | "x % 5 # x mod 5 = 1" 581 | ] 582 | }, 583 | { 584 | "cell_type": "code", 585 | "execution_count": null, 586 | "id": "cf0f0a93", 587 | "metadata": {}, 588 | "outputs": [ 589 | { 590 | "data": { 591 | "text/plain": [ 592 | "[1, 13, 78, 286, 715, 1287, 1716, 1716, 1287, 715, 286, 78, 13, 1]" 593 | ] 594 | }, 595 | "execution_count": 1, 596 | "metadata": {}, 597 | "output_type": "execute_result" 598 | } 599 | ], 600 | "source": [ 601 | "[binomial(13,m) for m in range(14)]" 602 | ] 603 | }, 604 | { 605 | "cell_type": "code", 606 | "execution_count": null, 607 | "id": "189272a2", 608 | "metadata": {}, 609 | "outputs": [ 610 | { 611 | "data": { 612 | "text/plain": [ 613 | "[1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1]" 614 | ] 615 | }, 616 | "execution_count": 1, 617 | "metadata": {}, 618 | "output_type": "execute_result" 619 | } 620 | ], 621 | "source": [ 622 | "[binomial(13,m)%2 for m in range(14)]" 623 | ] 624 | }, 625 | { 626 | "cell_type": "code", 627 | "execution_count": null, 628 | "id": "c3242716", 629 | "metadata": {}, 630 | "outputs": [ 631 | { 632 | "data": { 633 | "text/plain": [ 634 | "[1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1]" 635 | ] 636 | }, 637 | "execution_count": 1, 638 | "metadata": {}, 639 | "output_type": "execute_result" 640 | } 641 | ], 642 | "source": [ 643 | "[kronecker(m,13) for m in range(1,13)]" 644 | ] 645 | }, 646 | { 647 | "cell_type": "code", 648 | "execution_count": null, 649 | "id": "f4f95567", 650 | "metadata": {}, 651 | "outputs": [ 652 | { 653 | "data": { 654 | "text/plain": [ 655 | "-23" 656 | ] 657 | }, 658 | "execution_count": 1, 659 | "metadata": {}, 660 | "output_type": "execute_result" 661 | } 662 | ], 663 | "source": [ 664 | "n = 10000; sum([moebius(m) for m in range(1,n)])" 665 | ] 666 | }, 667 | { 668 | "cell_type": "code", 669 | "execution_count": null, 670 | "id": "0a25f240", 671 | "metadata": {}, 672 | "outputs": [ 673 | { 674 | "data": { 675 | "text/plain": [ 676 | "[[4], [3, 1], [2, 2], [2, 1, 1], [1, 1, 1, 1]]" 677 | ] 678 | }, 679 | "execution_count": 1, 680 | "metadata": {}, 681 | "output_type": "execute_result" 682 | } 683 | ], 684 | "source": [ 685 | "Partitions(4).list()" 686 | ] 687 | }, 688 | { 689 | "cell_type": "markdown", 690 | "id": "61ee72b4", 691 | "metadata": {}, 692 | "source": [ 693 | "## $p$-adic Numbers\n", 694 | "\n", 695 | "The field of $p$-adic numbers is implemented in Sage. Note that once a\n", 696 | "$p$-adic field is created, you cannot change its precision." 697 | ] 698 | }, 699 | { 700 | "cell_type": "code", 701 | "execution_count": null, 702 | "id": "b46854e9", 703 | "metadata": {}, 704 | "outputs": [ 705 | { 706 | "data": { 707 | "text/plain": [ 708 | "11-adic Field with capped relative precision 20" 709 | ] 710 | }, 711 | "execution_count": 1, 712 | "metadata": {}, 713 | "output_type": "execute_result" 714 | } 715 | ], 716 | "source": [ 717 | "K = Qp(11); K" 718 | ] 719 | }, 720 | { 721 | "cell_type": "code", 722 | "execution_count": null, 723 | "id": "b1f1b511", 724 | "metadata": {}, 725 | "outputs": [ 726 | { 727 | "data": { 728 | "text/plain": [ 729 | "4 + 4*11 + 11^2 + 7*11^3 + 9*11^5 + 5*11^6 + 4*11^7 + 8*11^8 + 7*11^9\n", 730 | " + 9*11^10 + 3*11^11 + 10*11^12 + 11^13 + 5*11^14 + 6*11^15 + 2*11^16\n", 731 | " + 3*11^17 + 11^18 + 7*11^19 + O(11^20)" 732 | ] 733 | }, 734 | "execution_count": 1, 735 | "metadata": {}, 736 | "output_type": "execute_result" 737 | } 738 | ], 739 | "source": [ 740 | "a = K(211/17); a" 741 | ] 742 | }, 743 | { 744 | "cell_type": "code", 745 | "execution_count": null, 746 | "id": "1abfc69b", 747 | "metadata": {}, 748 | "outputs": [ 749 | { 750 | "data": { 751 | "text/plain": [ 752 | "10*11^-2 + 5*11^-1 + 4 + 2*11 + O(11^18)" 753 | ] 754 | }, 755 | "execution_count": 1, 756 | "metadata": {}, 757 | "output_type": "execute_result" 758 | } 759 | ], 760 | "source": [ 761 | "b = K(3211/11^2); b" 762 | ] 763 | }, 764 | { 765 | "cell_type": "markdown", 766 | "id": "cfa444f5", 767 | "metadata": {}, 768 | "source": [ 769 | "Much work has been done implementing rings of integers in $p$-adic\n", 770 | "fields and number fields. The interested reader is invited to read\n", 771 | "`sage.rings.padics.tutorial` and ask the experts on the `sage-support`\n", 772 | "Google group for further details.\n", 773 | "\n", 774 | "A number of related methods are already implemented in the NumberField\n", 775 | "class." 776 | ] 777 | }, 778 | { 779 | "cell_type": "code", 780 | "execution_count": null, 781 | "id": "72bfcdbc", 782 | "metadata": {}, 783 | "outputs": [ 784 | { 785 | "data": { 786 | "text/plain": [ 787 | "[1, 1/2*a^2 + 1/2*a, a^2]" 788 | ] 789 | }, 790 | "execution_count": 1, 791 | "metadata": {}, 792 | "output_type": "execute_result" 793 | } 794 | ], 795 | "source": [ 796 | "R. = PolynomialRing(QQ)\n", 797 | "K = NumberField(x^3 + x^2 - 2*x + 8, 'a')\n", 798 | "K.integral_basis()" 799 | ] 800 | }, 801 | { 802 | "cell_type": "code", 803 | "execution_count": null, 804 | "id": "1c02e4b2", 805 | "metadata": {}, 806 | "outputs": [ 807 | { 808 | "data": { 809 | "text/plain": [ 810 | "Galois group 3T2 (S3) with order 6 of x^3 + x^2 - 2*x + 8" 811 | ] 812 | }, 813 | "execution_count": 1, 814 | "metadata": {}, 815 | "output_type": "execute_result" 816 | } 817 | ], 818 | "source": [ 819 | "K.galois_group()" 820 | ] 821 | }, 822 | { 823 | "cell_type": "code", 824 | "execution_count": null, 825 | "id": "7bd41c0a", 826 | "metadata": {}, 827 | "outputs": [ 828 | { 829 | "data": { 830 | "text/plain": [ 831 | "Univariate Quotient Polynomial Ring in a over Rational Field with modulus\n", 832 | "x^3 + x^2 - 2*x + 8" 833 | ] 834 | }, 835 | "execution_count": 1, 836 | "metadata": {}, 837 | "output_type": "execute_result" 838 | } 839 | ], 840 | "source": [ 841 | "K.polynomial_quotient_ring()" 842 | ] 843 | }, 844 | { 845 | "cell_type": "code", 846 | "execution_count": null, 847 | "id": "12210edd", 848 | "metadata": {}, 849 | "outputs": [ 850 | { 851 | "data": { 852 | "text/plain": [ 853 | "(3*a^2 + 13*a + 13,)" 854 | ] 855 | }, 856 | "execution_count": 1, 857 | "metadata": {}, 858 | "output_type": "execute_result" 859 | } 860 | ], 861 | "source": [ 862 | "K.units()" 863 | ] 864 | }, 865 | { 866 | "cell_type": "code", 867 | "execution_count": null, 868 | "id": "02b31038", 869 | "metadata": {}, 870 | "outputs": [ 871 | { 872 | "data": { 873 | "text/plain": [ 874 | "-503" 875 | ] 876 | }, 877 | "execution_count": 1, 878 | "metadata": {}, 879 | "output_type": "execute_result" 880 | } 881 | ], 882 | "source": [ 883 | "K.discriminant()" 884 | ] 885 | }, 886 | { 887 | "cell_type": "code", 888 | "execution_count": null, 889 | "id": "2a4618ec", 890 | "metadata": {}, 891 | "outputs": [ 892 | { 893 | "data": { 894 | "text/plain": [ 895 | "Class group of order 1 of Number Field in a with\n", 896 | "defining polynomial x^3 + x^2 - 2*x + 8" 897 | ] 898 | }, 899 | "execution_count": 1, 900 | "metadata": {}, 901 | "output_type": "execute_result" 902 | } 903 | ], 904 | "source": [ 905 | "K.class_group()" 906 | ] 907 | }, 908 | { 909 | "cell_type": "code", 910 | "execution_count": null, 911 | "id": "0b2a8f41", 912 | "metadata": {}, 913 | "outputs": [ 914 | { 915 | "data": { 916 | "text/plain": [ 917 | "1" 918 | ] 919 | }, 920 | "execution_count": 1, 921 | "metadata": {}, 922 | "output_type": "execute_result" 923 | } 924 | ], 925 | "source": [ 926 | "K.class_number()" 927 | ] 928 | } 929 | ], 930 | "metadata": {}, 931 | "nbformat": 4, 932 | "nbformat_minor": 5 933 | } 934 | --------------------------------------------------------------------------------