On peut se servir de Python/Sage comme d'une calculette

In [1]:
1+1
Out[1]:
2
In [2]:
a = 3
a + a
Out[2]:
6

Les noms de variables non-déclarés donnent une erreur

In [3]:
c
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-3-2cd6ee2c70b0> in <module>()
----> 1 c

NameError: name 'c' is not defined

Mais attention : l'ordre des cellules peut être trompeur. Ici nous évaluons d'abord deux cellules plus bas (In [4]), puis la cellule immédiatement en bas In [5]. Les cellules peuvent aussi être déplacées après coup.

In [5]:
b
Out[5]:
1
In [4]:
b = 1

Dans les cellules de type Markdown

Je peux ecrire des commentaires!

Des gros titres

Des moins gros titres

des tout petits titres

On peut ecrire du LaTeX: $\int_0^\pi sin(x)dx$

Python vs Sage

Contrairement à Python, Sage représente les objets mathématiques de façon exacte (lorsque cela est possible)

In [6]:
# Evalué dans un noyau Python 3
5 / 3
Out[6]:
1.6666666666666667
In [7]:
# Dans un noyau Sage
a = 5 / 3
a
Out[7]:
5/3

L'évaluation numérique d'une valeur exacte peut se demander à l'aide de la méthode .n()

In [8]:
a.n(100)
Out[8]:
1.6666666666666666666666666667
In [9]:
pi
Out[9]:
pi
In [10]:
pi.n(1000)
Out[10]:
3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593344612847564823378678316527120190914564856692346034861045432664821339360726024914127

Tout élément d'un ensemble mathématique dans Sage (pas dans Python) possède un parent

In [11]:
parent(a)
Out[11]:
Rational Field

Le quotient de la division entière s'obtient avec l'opérateur //

In [12]:
b = 5 // 3
b
Out[12]:
1
In [13]:
parent(b)
Out[13]:
Integer Ring

Bien sûr, ces entiers ne sont pas limités à la précision de la machine (64 bits)

In [14]:
2^2000
Out[14]:
114813069527425452423283320117768198402231770208869520047764273682576626139237031385665948631650626991844596463898746277344711896086305533142593135616665318539129989145312280000688779148240044871428926990063486244781615463646388363947317026040466353970904996558162398808944629605623311649536164221970332681344168908984458505602379484807914058900934776500429002716706625830522008132236281291761267883317206598995396418127021779858404042159853183251540889433902091920554957783589672039160081957216630582755380425583726015528348786419432054508915275783882625175435528800822842770817965453762184851149029376

Affichage en mode latex

In [15]:
%display latex
In [16]:
3 / 5
Out[16]:
In [17]:
(x^3+1)/(x^2+1)
Out[17]:
In [18]:
parent(a)
Out[18]:
In [19]:
parent(b)
Out[19]:
In [20]:
%display plain
In [21]:
parent(b)
Out[21]:
Integer Ring

Obtenir la documentation interactive

Utiliser la touche "tab" pour compléter un nom

In [22]:
SymmetricGroup?
In [23]:
S = SymmetricGroup(10)
S
Out[23]:
Symmetric group of order 10! as a permutation group

Certaines structures permettent d'obtenir quelques exemples d'éléments non-triviaux

In [24]:
S.an_element()
Out[24]:
(1,2,3,4,5,6,7,8,9,10)
In [25]:
S.some_elements()
Out[25]:
[(1,2),
 (2,3),
 (3,4),
 (4,5),
 (5,6),
 (6,7),
 (7,8),
 (8,9),
 (9,10),
 (),
 (1,2,3,4,5,6,7,8,9,10)]

Pour obtenir le code source à la place de la documentation

In [26]:
SymmetricGroup??

Méthodes

La plus part des fonctionalités en Sage est accessible par des méthodes définies sur les objets.

Astuce: après le point (.) utilisez la touche "tab" pour obtenir la liste des méthodes.

In [27]:
a.continued_fraction()
Out[27]:
[1; 1, 2]
In [28]:
35.gcd(45)
Out[28]:
5
In [29]:
i.conjugate()
Out[29]:
-I

Quelques structures algèbriques pré-définies

In [30]:
ZZ
Out[30]:
Integer Ring
In [31]:
IntegerRing()
Out[31]:
Integer Ring
In [32]:
QQ
Out[32]:
Rational Field
In [33]:
RR
Out[33]:
Real Field with 53 bits of precision
In [34]:
CC
Out[34]:
Complex Field with 53 bits of precision
In [35]:
RealField(prec=1000)
Out[35]:
Real Field with 1000 bits of precision
In [36]:
GF(101)
Out[36]:
Finite Field of size 101
In [37]:
GF(101^3)
Out[37]:
Finite Field in z3 of size 101^3

Anneaux de polynômes

In [38]:
ZZ["X"]
Out[38]:
Univariate Polynomial Ring in X over Integer Ring
In [39]:
QQ['Y']
Out[39]:
Univariate Polynomial Ring in Y over Rational Field
In [40]:
QQ['X,Y']['Z']
Out[40]:
Univariate Polynomial Ring in Z over Multivariate Polynomial Ring in X, Y over Rational Field

Variables: mathématiques et langage de programmation

Le fait d'avoir défini un anneau de polynômes en la variable $X$ ne définit pas pour autant une variable Python du même nom

In [41]:
X
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-41-253bcac7dd80> in <module>()
----> 1 X

NameError: name 'X' is not defined

Pour éviter de confondre les deux concepts, nous appelerons la variable mathématique $X$ un générateur de l'anneau de polynômes, ou encore un élément transcendant.

Sa représentation informatique est obtenue par la méthode .gen() (ou .gens() pour des anneaux à plusieurs variables).

On peut, bien sûr, assigner le générateur à une variable Python de même nom

In [42]:
A = QQ['X']
A
Out[42]:
Univariate Polynomial Ring in X over Rational Field
In [43]:
X = A.gen()
In [44]:
X
Out[44]:
X
In [45]:
parent(X)
Out[45]:
Univariate Polynomial Ring in X over Rational Field
In [46]:
parent(X) is A
Out[46]:
True
In [47]:
(X^2 + 3)^10
Out[47]:
X^20 + 30*X^18 + 405*X^16 + 3240*X^14 + 17010*X^12 + 61236*X^10 + 153090*X^8 + 262440*X^6 + 295245*X^4 + 196830*X^2 + 59049

La même chose peut s'écrire sur une seule ligne avec la syntaxe spéciale (spécifique à Sage, pas valide en Python):

In [48]:
A.<Y> = QQ['Y']
In [49]:
A
Out[49]:
Univariate Polynomial Ring in Y over Rational Field
In [50]:
Y
Out[50]:
Y

La variable python n'a aucune obligation de s'appeler comme le générateur

In [51]:
A.<toto> = QQ['Z']
In [52]:
A
Out[52]:
Univariate Polynomial Ring in Z over Rational Field
In [53]:
toto
Out[53]:
Z
In [54]:
Z
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-54-41ff0912a07f> in <module>()
----> 1 Z

NameError: name 'Z' is not defined

Syntaxe encore plus courte: le générateur prend le même nom que la variable

In [55]:
A.<titi> = QQ[]
In [56]:
A
Out[56]:
Univariate Polynomial Ring in titi over Rational Field
In [57]:
titi
Out[57]:
titi
In [58]:
(titi^2+1)^6
Out[58]:
titi^12 + 6*titi^10 + 15*titi^8 + 20*titi^6 + 15*titi^4 + 6*titi^2 + 1

Anneau symbolique vs anneaux de polynômes

Une structure qui apparaît souvent dans Sage (et qu'on va fuire comme la peste) est l'anneau symbolique

In [59]:
SR
Out[59]:
Symbolic Ring
In [60]:
parent(pi)
Out[60]:
Symbolic Ring
In [61]:
sin(pi)
Out[61]:
0
In [62]:
parent(sin(pi))
Out[62]:
Symbolic Ring
In [63]:
derivative(sin(x))
Out[63]:
cos(x)
In [64]:
parent(sin(x))
Out[64]:
Symbolic Ring

La variable pré-définie $x$

En plus de valeurs exactes, comme $π$, l'anneau symbolique peut contenir des variables symboliques, et des fonctions en ces variables.

Le concept de variable symbolique est distinct des concepts de variable Python et de générateur d'un anneau de polynômes.

Au démarrage d'une session Sage, il existe une variable symbolique pré-définie, nommée $x$.

In [65]:
x
Out[65]:
x
In [66]:
x^2 + 1
Out[66]:
x^2 + 1
In [67]:
parent(x)
Out[67]:
Symbolic Ring

Les expressions polynomiales en les variables symboliques ne sont pas évaluées immédiatement

In [69]:
toto = (x^2 + 1)^5
toto
Out[69]:
(x^2 + 1)^5
In [70]:
toto.expand()
Out[70]:
x^10 + 5*x^8 + 10*x^6 + 10*x^4 + 5*x^2 + 1

Le nom x n'a rien de spécial: il s'agit d'une variable Python quelconque, qui se trouve avoir été assignée à une variable symbolique.

On peut remplacer sa valeur avec une valeur quelconque

In [71]:
x = 3
In [72]:
x
Out[72]:
3
In [73]:
parent(x)
Out[73]:
Integer Ring
In [74]:
pi = 3
In [75]:
pi
Out[75]:
3

Récupérons tout de même la valeur originale de $π$...

In [76]:
pi = sage.all.pi
In [77]:
pi
Out[77]:
pi

On peut définir autant de variables symboliques que l'on souhaite, avec le constructeur SR.var()

In [78]:
x = SR.var('x')
In [79]:
x
Out[79]:
x
In [80]:
parent(x)
Out[80]:
Symbolic Ring

Même gotcha que pour les anneaux de polynômes: la variable Python peut avoir un nom différent de la variable symbolique

In [81]:
toto = SR.var('y')
In [82]:
y
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-82-009520053b00> in <module>()
----> 1 y

NameError: name 'y' is not defined
In [83]:
toto
Out[83]:
y
In [84]:
parent(toto)
Out[84]:
Symbolic Ring

Et enfin, il existe ici aussi une version courte pour définir d'un seul coup une variable symbolique assignée à une variable Python du même nom

In [85]:
var('z')
Out[85]:
z
In [86]:
z
Out[86]:
z