Support du cours 5

Objectifs :

  • représentations des entiers, rationnels, réels et complexes dans SageMath
  • calculs sur ces éléments
  • quelques fonctions de base
  • obtenir de l'aide avec sagemath

Entiers

Avec sagemath, on peut déclarer et utiliser les entiers comme en python. En revanche, leur type a changé : ce sont maintenant des membres d'une classe appelée Integer. Enfin, on leur assigne un "parent", l'anneau des entiers, qui peut être obtenu par ZZ, ou par IntegerRing()

In [1]:
a = 1
a
Out[1]:
1
In [2]:
type(a)
Out[2]:
<class 'sage.rings.integer.Integer'>
In [3]:
parent(a)
Out[3]:
Integer Ring
In [4]:
ZZ
Out[4]:
Integer Ring
In [5]:
IntegerRing() == ZZ
Out[5]:
True

Remarque : SageMath sait que ZZ est un anneau.

In [6]:
ZZ.is_ring()
Out[6]:
True

On peut également y tirer des éléments aléatoires :

In [7]:
ZZ.random_element()
Out[7]:
1

Avec sagemeth, on peut faire des calculs comme en python. les opérations élémentaires sont identiques.

In [8]:
x = 17
((x % 5)**123 + 3*x - 2)//8
Out[8]:
1329227995784915872903807060280344582

On peut appliquer des fonctions externes aux entiers, par exemple la fonction gcd qui calcule un pgcd, ou la fonction xgcd qui calcule également les coefficients de Bezout.

In [9]:
gcd(12, 27)
Out[9]:
3
In [10]:
xgcd(12, 27)
Out[10]:
(3, -2, 1)

Remarque importante : Pour savoir comment utiliser une fonction, on peut s'aider de l'aide interactive de sagemath. Pour cela, il faut taper le nom de la fonction suivi de ?. Une mini-fenêtre s'ouvre alors avec l'aide (en anglais) associée à la fonction. Exemple :

In [11]:
# gcd?

On peut également factoriser un entier avec la fonction externe factor. Pour obtenir la liste des facteurs premiers et leur multiplicités associées, il faut réécrire la sortie sous forme de liste.

In [12]:
factor(1234567890)
Out[12]:
2 * 3^2 * 5 * 3607 * 3803
In [13]:
list(factor(1234567890))
Out[13]:
[(2, 1), (3, 2), (5, 1), (3607, 1), (3803, 1)]

Il existe beaucoup d'autres fonctions comme binomial, factorial, ...

Il existe aussi des fonctions qui s'appliquent directement à l'objet entier. On appelle ces fonctions des méthodes. Par exemple, pour deux entiers a et b, la commande a.quo_rem(b) renvoie le quotient et le reste de la division euclidienne de a par b. Ici, on voit qu'on applique la fonction quo_rem à a avec le paramètre b.

In [14]:
a = 12
a.quo_rem(7)
Out[14]:
(1, 5)

Il existe beaucoup d'autres méthodes à utiliser directement sur un entier, comme par exemple is_prime() ou inverse_mod(n)

In [15]:
a.is_prime()
Out[15]:
False
In [16]:
a.inverse_mod(23)
Out[16]:
2

Remarque importante : Pour voir quelles méthodes on peut appliquer à un objet a, on peut utiliser la complétion automatique de sagemath. Par exemple, on tape a.<Tab>, où <Tab> est la touche de tabulation.

Cette technique est très utile, car elle permet de découvrir quelles fonctions on peut appliquer aux objets que l'on crée.

Par exemple, avec un entier :

In [17]:
a = Integer(12)
# a.

Rationnels

Les nombres srationnels sont stockés de manière exacte et réduite dans SageMath. Leur parent est RationalField(), abrégé en QQ.

In [18]:
a = 4
b = 6
x = a/b
x
Out[18]:
2/3
In [19]:
type(x)
Out[19]:
<class 'sage.rings.rational.Rational'>
In [20]:
parent(x)
Out[20]:
Rational Field
In [21]:
QQ
Out[21]:
Rational Field
In [22]:
QQ == RationalField()
Out[22]:
True
In [23]:
QQ.is_ring() and QQ.is_field()
Out[23]:
True

On peut également en tirer des éléments aléatoires.

In [24]:
[ QQ.random_element() for i in range(10) ]
Out[24]:
[-3/4, -1/2, 1, -1/2, 0, -1, -2, 6, -4, 1/2]

Pour voir un entier x comme un rationnel, il faut caster l'élément, autrement dit le convertir, le "retyper". Pour cela, on utilise la commande QQ(x).

In [25]:
x = 2
print(parent(x))
y = QQ(x)
print(parent(y))
Integer Ring
Rational Field

Attention : si vous souhaitez caster un rationnel comme un entier, il faut que cela soit possible, sinon vous obtiendrez une erreur de conversion.

In [26]:
# ZZ(2/3)

Comme pour les entiers, il existe des méthodes à appliquer aux rationnels.

In [27]:
a = QQ(4/-6)
print(a.denominator())
print(a.numerator())
3
-2

Réels

Les nombres réels sont stockés avec une certain précision dans SageMath. On peut choisir la précision, mais elle est de 53 bits par défaut.

In [28]:
a = 1.0
a
Out[28]:
1.00000000000000
In [29]:
type(a)
Out[29]:
<class 'sage.rings.real_mpfr.RealLiteral'>
In [30]:
parent(a)
Out[30]:
Real Field with 53 bits of precision
In [31]:
RR
Out[31]:
Real Field with 53 bits of precision
In [32]:
RealField()
Out[32]:
Real Field with 53 bits of precision

Pour changer la précision, il faut ajouter un paramètre à RealField, ici 1000 par exemple :

In [33]:
RealField(1000)
Out[33]:
Real Field with 1000 bits of precision

Dans des calculs très précis, cela peut avoir de l'importance :

In [34]:
A = RealField()
B = RealField(1000)

gros_nombre_A = A(2**123)
gros_nombre_B = B(2**123)

x = 1 + 1 / gros_nombre_A
y = 1 + 1 / gros_nombre_B

print("Avec 53 bits de précision : x vaut 1 ?", x == 1)
print("Avec 1000 bits de précision : y vaut 1 ?", y == 1)
Avec 53 bits de précision : x vaut 1 ? True
Avec 1000 bits de précision : y vaut 1 ? False
In [35]:
RR(2/3)
Out[35]:
0.666666666666667

On peut passer de réels à rationnels et vice versa. Mais il faut toujours garder en mémoire que les réels sont une approximation !

In [36]:
x = 2/3 + 1/(2**123)
y = RR(x)

print(QQ(y))
print(QQ(y) == QQ(x))
2/3
False
In [ ]:
 

Nombres complexes

Les nombres complexes sont implantés dans SageMath, avec comme parent ComplexField() abrégé en CC. Comme pour les réels, le corps des nombres complexes est instancié avec 53 bits de précision par défaut, mais peut être choisi arbitrairement en rajoutant la précision en paramètre de ComplexField.

In [37]:
CC
Out[37]:
Complex Field with 53 bits of precision

Le nombre imaginaire est représenté par I.

In [38]:
I
Out[38]:
I
In [39]:
I**2
Out[39]:
-1
In [40]:
I in CC, I in RR
Out[40]:
(True, False)

Remarque : Si vous écrasez la variable I dans un de vos calculs, vous pouvez toujours récupérer la valeur de I grâce à CC.gen()

In [41]:
J = CC.gen()
I.parent().gen()
Out[41]:
I

On peut naturellement faire des opérations sur les complexes, et leur appliquer des méthodes, comme conjugate() ou norm() pour avoir le conjugué d'un complexe, ou sa norme.

In [42]:
12 - 3*I
Out[42]:
-3*I + 12
In [43]:
z = 1 - I
z.conjugate()
Out[43]:
I + 1
In [44]:
z.norm()
Out[44]:
2
In [45]:
z.real_part(), z.imag_part()
Out[45]:
(1, -1)
In [46]:
arg(z)
Out[46]:
-1/4*pi
In [47]:
abs(z)
Out[47]:
sqrt(2)

Fonctions et valeurs spéciales

Beaucoup de fonctions et valeurs sont déjà implantées dans sagemath.

In [48]:
pi
Out[48]:
pi
In [49]:
RR(pi)
Out[49]:
3.14159265358979
In [50]:
RealField(10000)(pi)
Out[50]:
3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593344612847564823378678316527120190914564856692346034861045432664821339360726024914127372458700660631558817488152092096282925409171536436789259036001133053054882046652138414695194151160943305727036575959195309218611738193261179310511854807446237996274956735188575272489122793818301194912983367336244065664308602139494639522473719070217986094370277053921717629317675238467481846766940513200056812714526356082778577134275778960917363717872146844090122495343014654958537105079227968925892354201995611212902196086403441815981362977477130996051870721134999999837297804995105973173281609631859502445945534690830264252230825334468503526193118817101000313783875288658753320838142061717766914730359825349042875546873115956286388235378759375195778185778053217122680661300192787661119590921642019893809525720106548586327886593615338182796823030195203530185296899577362259941389124972177528347913151557485724245415069595082953311686172785588907509838175463746493931925506040092770167113900984882401285836160356370766010471018194295559619894676783744944825537977472684710404753464620804668425906949129331367702898915210475216205696602405803815019351125338243003558764024749647326391419927260426992279678235478163600934172164121992458631503028618297455570674983850549458858692699569092721079750930295532116534498720275596023648066549911988183479775356636980742654252786255181841757467289097777279380008164706001614524919217321721477235014144197356854816136115735255213347574184946843852332390739414333454776241686251898356948556209921922218427255025425688767179049460165346680498862723279178608578438382796797668145410095388378636095068006422512520511739298489608412848862694560424196528502221066118630674427862203919494504712371378696095636437191728746776465757396241389086583264599581339047802759009946576407895126946839835259570982582262052248940772671947826848260147699090264013639443745530506820349625245174939965143142980919065925093722169646151570985838741059788595977297549893016175392846813826868386894277415599185592524595395943104997252468084598727364469584865383673622262609912460805124388439045124413654976278079771569143599770012961608944169486855584840635342207222582848864815845602850601684273945226746767889525213852254995466672782398645659611635488623057745649803559363456817432411251507606947945109659609402522887971089314566913686722874894056010150330861792868092087476091782493858900971490967598526136554978189312978482168299894872265880485756401427047755513237964145152374623436454285844479526586782105114135473573952311342716610213596953623144295248493718711014576540359027993440374200731057853906219838744780847848968332144571386875194350643021845319104848100537061468067491927819119793995206141966342875444064374512371819217999839101591956181467514269123974894090718649423196156794521
In [51]:
e, RR(e)
Out[51]:
(e, 2.71828182845905)
In [52]:
exp(1)
Out[52]:
e
In [53]:
ln(e)
Out[53]:
1
In [54]:
log(32, 2)
Out[54]:
5
In [55]:
cos(pi/2), sin(pi/2)
Out[55]:
(0, 1)
In [56]:
2*exp(I*pi/4)
Out[56]:
(I + 1)*sqrt(2)
In [57]:
sqrt(4)
Out[57]:
2
In [58]:
pow(16, 1/4)
Out[58]:
2
In [59]:
pow(3, 1/4)
Out[59]:
3^(1/4)
In [60]:
pow(3.0, 1/4)
Out[60]:
1.31607401295249

Affichage graphique

Pour l'affichage, il n'y a plus besoin d'importer la bibliothèque matplotlib. Il existe beaucoup de fonctions d'affichage. Des détails ici pour les fonctions d'affichage en 2D :

https://doc.sagemath.org/html/en/reference/plotting/sage/plot/plot.html

La plus simple est plot, et elle prend en entrée une fonction (et non une liste de points comme avec matplotlib). Pour la fonction exponentielle :

In [61]:
plot(exp)
Out[61]:

Sagemath choisit lui-même par défaut un domaine d'affichage, et crée la liste de points à afficher. Parfois, il peut retourner des avertissements (car il essaie de calculer des valeurs non-définies). Par exemple avec la fonction $\ln$ :

In [62]:
plot(ln)
verbose 0 (3839: plot.py, generate_plot_points) WARNING: When plotting, failed to evaluate function at 100 points.
verbose 0 (3839: plot.py, generate_plot_points) Last error message: 'Unable to compute f(-0.009387346392616206)'
Out[62]:

On peut arranger cela en spécifiant les bornes des abscisses pour l'affichage (ici $x \in [1, 100]$) :

In [63]:
plot(ln, xmin=1, xmax=100)
Out[63]:

Avec une manière compacte :

In [64]:
plot(ln, [1, 100])
Out[64]:

Il est également possible d'afficher plusieurs fonctions en même temps. Pour cela on peut créer une liste de fonctions :

In [65]:
plot([ln, sqrt], xmin=1, xmax=100)
Out[65]:

On peut également "additionner" les graphiques (c'est très commode !) :

In [66]:
plot(ln, xmin=1, xmax=100) + plot(sqrt, xmin=1, xmax=100, color="green")
Out[66]:

Pour afficher des points, il y a la commande graphique points

In [67]:
points([[cos(2*i*pi/36), sin(2*i*pi/36)] for i in range(36)])
Out[67]:

On peut obtenir un "vrai" cercle en changeant le ratio d'affichage.

In [68]:
points([[cos(2*i*pi/36), sin(2*i*pi/36)] for i in range(36)], aspect_ratio=1)
Out[68]:

Pour l'affichage 3D, il y a la fonction plot3d :

In [69]:
var('x y')  # ici, je déclare mes variables x et y (la syntaxe est très spéciale...)
plot3d(x**2 + y**2, [-2, 2], [-2, 2], opacity=0.8)
Out[69]:
In [70]:
P = plot3d(sqrt(8*(x**2 + y**2)), [-10, 10], [-10, 10], opacity=0.5, frame=False)
Q = plot3d(x + 0.5*y + 12, [-10, 10], [-10, 10], opacity=0.5, frame=False, color="red")
P+Q
Out[70]: