├── 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 |
--------------------------------------------------------------------------------