Objectifs :
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()
a = 1
a
type(a)
parent(a)
ZZ
IntegerRing() == ZZ
Remarque : SageMath sait que ZZ
est un anneau.
ZZ.is_ring()
On peut également y tirer des éléments aléatoires :
ZZ.random_element()
Avec sagemeth, on peut faire des calculs comme en python. les opérations élémentaires sont identiques.
x = 17
((x % 5)**123 + 3*x - 2)//8
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.
gcd(12, 27)
xgcd(12, 27)
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 :
# 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.
factor(1234567890)
list(factor(1234567890))
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
.
a = 12
a.quo_rem(7)
Il existe beaucoup d'autres méthodes à utiliser directement sur un entier, comme par exemple is_prime()
ou inverse_mod(n)
a.is_prime()
a.inverse_mod(23)
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 :
a = Integer(12)
# a.
Les nombres srationnels sont stockés de manière exacte et réduite dans SageMath. Leur parent est RationalField()
, abrégé en QQ
.
a = 4
b = 6
x = a/b
x
type(x)
parent(x)
QQ
QQ == RationalField()
QQ.is_ring() and QQ.is_field()
On peut également en tirer des éléments aléatoires.
[ QQ.random_element() for i in range(10) ]
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)
.
x = 2
print(parent(x))
y = QQ(x)
print(parent(y))
Attention : si vous souhaitez caster un rationnel comme un entier, il faut que cela soit possible, sinon vous obtiendrez une erreur de conversion.
# ZZ(2/3)
Comme pour les entiers, il existe des méthodes à appliquer aux rationnels.
a = QQ(4/-6)
print(a.denominator())
print(a.numerator())
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.
a = 1.0
a
type(a)
parent(a)
RR
RealField()
Pour changer la précision, il faut ajouter un paramètre à RealField
, ici 1000
par exemple :
RealField(1000)
Dans des calculs très précis, cela peut avoir de l'importance :
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)
RR(2/3)
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 !
x = 2/3 + 1/(2**123)
y = RR(x)
print(QQ(y))
print(QQ(y) == QQ(x))
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
.
CC
Le nombre imaginaire est représenté par I
.
I
I**2
I in CC, I in RR
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()
J = CC.gen()
I.parent().gen()
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.
12 - 3*I
z = 1 - I
z.conjugate()
z.norm()
z.real_part(), z.imag_part()
arg(z)
abs(z)
Beaucoup de fonctions et valeurs sont déjà implantées dans sagemath.
pi
RR(pi)
RealField(10000)(pi)
e, RR(e)
exp(1)
ln(e)
log(32, 2)
cos(pi/2), sin(pi/2)
2*exp(I*pi/4)
sqrt(4)
pow(16, 1/4)
pow(3, 1/4)
pow(3.0, 1/4)
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 :
plot(exp)
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$ :
plot(ln)
On peut arranger cela en spécifiant les bornes des abscisses pour l'affichage (ici $x \in [1, 100]$) :
plot(ln, xmin=1, xmax=100)
Avec une manière compacte :
plot(ln, [1, 100])
Il est également possible d'afficher plusieurs fonctions en même temps. Pour cela on peut créer une liste de fonctions :
plot([ln, sqrt], xmin=1, xmax=100)
On peut également "additionner" les graphiques (c'est très commode !) :
plot(ln, xmin=1, xmax=100) + plot(sqrt, xmin=1, xmax=100, color="green")
Pour afficher des points, il y a la commande graphique points
points([[cos(2*i*pi/36), sin(2*i*pi/36)] for i in range(36)])
On peut obtenir un "vrai" cercle en changeant le ratio d'affichage.
points([[cos(2*i*pi/36), sin(2*i*pi/36)] for i in range(36)], aspect_ratio=1)
Pour l'affichage 3D, il y a la fonction plot3d
:
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)
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