Feuille d’exercices 5#

Objectifs

  • Introduction à Sagemath

  • Calcul exact : entiers, rationnels, complexes

  • Notions sur le calcul symbolique

  • Notion de méthode et de classe

Exercice 1. Manipulation élémentaire d’entiers, de rationnels et de complexes#

Question 1. Donner la valeur exacte des quantités suivantes :

  • \(12!\)

  • le rationnel \(\frac{8778}{4557}\)

  • le plus petit nombre premier supérieur à \(2^{20}\)

  • \(\cos(2\pi/5)\)

  • la partie réelle de \(3 e^{7 i \pi/12}\)

  • l’argument de \(1+i\)

print(factorial(12))
print(8778/4557)
print(next_prime(2**20))
print(cos(2*pi/5))
print((3*e**(7*i*pi/12)).real_part())
print(arg(1+I))
479001600
418/217
1048583
1/4*sqrt(5) - 1/4
-3/4*sqrt(6) + 3/4*sqrt(2)
1/4*pi

Question 2. Écrire une fonction plus_petit_module(liste) qui prend en entrée une liste liste de nombres complexes, et qui retourne le nombre complexe de plus petit module de cette liste. Si la liste est vide, la fonction devra afficher un texte d’erreur, puis retourner le mot-clef None.

def plus_petit_module(liste):
    if liste == []:
        print("Erreur : la liste est vide")
        return None
    else:
        n = len(liste)
        element = liste[0]
        for i in range(1, n):
            if liste[i].abs() < element.abs():
                element = liste[i]
        return element

plus_petit_module([3+2*I, I/2, e**(I*pi/5) - e**(2*I*pi/3)])
1/2*I

Exercice 2. Somme de binomiaux#

Question 1. Écrire une fonction somme_newton(n) qui prend en entrée un entier n et qui retourne la valeur de la somme

\[\sum_{k=0}^n \binom{n}{k}.\]
def somme_newton(n):
    somme = 0
    for k in range(n+1):
        somme += binomial(n, k)
    return somme
    
somme_newton(4)
16

Question 2. Vérifier que pour tout \(n\) compris entre \(0\) et \(100\), l’égalité \(\sum_{k=0}^n \binom{n}{k} = 2^n\) est bien vérifiée.

all(somme_newton(n) == 2**n for n in range(101))
True

Question 3. Écrire une fonction somme_binomiaux(n) qui prend en entrée un entier n et qui retourne la valeur de la somme

\[ \sum_{k=0}^n \frac{(-1)^k}{k+1} \binom{n}{k}. \]

Puis, calculer plusieurs valeurs de cette somme, émettre une conjecture, puis la « vérifier » sur les valeurs de \(n\) comprises en \(0\) et \(100\).

def somme_binomiaux(n):
    somme = 0
    for k in range(n+1):
        somme += (-1)**k * binomial(n, k) / (k+1)
    return somme
    
print(somme_binomiaux(1))
print(somme_binomiaux(4))
print(somme_binomiaux(10))
1/2
1/5
1/11

Notre conjecture est que cette somme vaut toujours \(1/(n+1)\). Vérification :

all(somme_binomiaux(n) == 1/(n+1) for n in range(101))
True

Exercice 3. Double boucle#

Dans cet exercice, on considère une liste \(L = (L_0, \dots, L_{n-1})\) de rationnels distincts, de longueur \(n \ge 2\).

Question 1. Écrire une fonction produit_differences(L), qui prend en entrée la liste L de rationnels, et qui retourne la valeur du produit

\[ \prod_{0 \le i < j \le n-1} \frac{1}{L_j-L_i}\,. \]
def produit_differences(L):
    n = len(L)
    p = 1
    for i in range(n):
        for j in range(i+1,n):
            p /= (L[j] - L[i])
    return p

L = [ 3, 1/2, 7/3, -2/3 ]
print(produit_differences(L))
-108/4235

Question 2. Écrire une fonction plus_proches(L), qui prend en entrée la liste L de rationnels, et qui retourne la paire \((a, b)\) de rationnels les plus proches parmi toutes les paires d’éléments de la liste L.

def plus_proches(L):
    diff = abs(L[0]-L[1])
    n = len(L)
    for i in range(n):
        for j in range(i):
            if abs(L[i] - L[j]) < diff:
                paire = [L[i], L[j]]
                diff = abs(L[i] - L[j])
    return paire
    
L = [ 3, 1/2, 7/3, -2/3 ]
print(plus_proches(L))
[7/3, 3]

Exercice 4. Triplets pythagoriciens#

Un triplet pythagoricien est un triplet \((p, q, r) \in \mathbb{N}^3\) tel que \(p^2 + q^2 = r^2\). Observons que, si \((p, q, r)\) est un triplet pythagoricien, alors \(p \le r\) et \(q \le r\).

Question 1. Écrire une fonction trouve_triplets(r), qui prend entrée un entier naturel r, et qui retourne la liste de toutes les paires \((p, q)\) telles que \((p, q, r)\) forme un triplet pythagorien.

def trouve_triplets(r):
    return [ (p, q) for p in range(r+1) for q in range(r+1) if p**2 + q**2 == r**2 ]
    
trouve_triplets(5)
[(0, 5), (3, 4), (4, 3), (5, 0)]

Tout triplet pythagoricien peut être associé à un point du cercle unité dont les coordonnées sont des rationnels. En effet,

\[p^2 + q^2 = r^ 2 \iff (p/r)^2 + (q/r)^2 = 1 \iff (p/r, q/r) \, \text{ est un point rationnel du cercle unité } \]

Par ailleurs, si \((\alpha, \beta) \in \mathbb{Q}^2\) est sur le cercle unité, alors en écrivant \(\alpha = a/n\) et \(\beta = b/n\) sur le même dénominateur \(n\), on obtient un triplet pythagoricien \((a, b, n)\).

Question 2. Écrire une fonction triplet_vers_point(t, r) qui transforme un triplet pythagoricien formé de t=(p,q) et r, en un point du cercle unité (donné comme un couple de rationnels).

Pour s’assurer que les valeurs obtenues sont bien des rationnels, on effectuera une conversion de type des éléments de t vers la classe des entiers.

def triplet_vers_point(t, r):
    return (Integer(t[0])/r, Integer(t[1])/r)
    
triplet_vers_point([3, 4], 5)
(3/5, 4/5)

Question 3. Déduire de la question précédente une fonction trouve_points_rationnels(r_max), qui prend entrée un entier naturel r_max, et qui retourne la liste de tous les points rationnels \((x, y)\) du cercle unité, dont un dénominateur commun est \(r \le r_{max}\).

def trouve_points_rationnels(r_max):
    liste = []
    for r in range(1, r_max+1):
        pyth = trouve_triplets(r)
        ratio = [ triplet_vers_point(t, r) for t in pyth ]
        liste += ratio
    return liste
    
trouve_points_rationnels(10)
[(0, 1),
 (1, 0),
 (0, 1),
 (1, 0),
 (0, 1),
 (1, 0),
 (0, 1),
 (1, 0),
 (0, 1),
 (3/5, 4/5),
 (4/5, 3/5),
 (1, 0),
 (0, 1),
 (1, 0),
 (0, 1),
 (1, 0),
 (0, 1),
 (1, 0),
 (0, 1),
 (1, 0),
 (0, 1),
 (3/5, 4/5),
 (4/5, 3/5),
 (1, 0)]

On pourrait aussi écrire, de manière très compacte :

def trouve_points_rationnels(r_max):
    return [ triplet_vers_point(t, r) for r in range(1, r_max+1) for t in trouve_triplets(r) ]
    
# trouve_points_rationnels(10)

Question 4 (optionnelle). Éliminer les éventuels doublons (éléments répétés plusieurs fois) de la liste précédente pour obtenir une liste d’éléments distincts.

print("Pour r = 10 :", list(set(trouve_points_rationnels(10))))
print("Pour r = 30 :", list(set(trouve_points_rationnels(100))))
Pour r = 10 : [(0, 1), (1, 0), (3/5, 4/5), (4/5, 3/5)]
Pour r = 30 : [(5/13, 12/13), (63/65, 16/65), (12/13, 5/13), (60/61, 11/61), (77/85, 36/85), (1, 0), (12/37, 35/37), (35/37, 12/37), (65/97, 72/97), (36/85, 77/85), (72/97, 65/97), (21/29, 20/29), (11/61, 60/61), (20/29, 21/29), (8/17, 15/17), (0, 1), (33/65, 56/65), (24/25, 7/25), (15/17, 8/17), (13/85, 84/85), (56/65, 33/65), (84/85, 13/85), (9/41, 40/41), (45/53, 28/53), (7/25, 24/25), (48/73, 55/73), (80/89, 39/89), (3/5, 4/5), (55/73, 48/73), (4/5, 3/5), (40/41, 9/41), (39/89, 80/89), (16/65, 63/65), (28/53, 45/53)]

Exercice 5. Transformations complexes#

Question 1 : Créer la liste L des nombres complexes \((1, i, -1, -i)\). Puis, exécutez l’instruction polygon(L).show(). Qu’observez-vous ?

L = [1, I, -1, -I]
polygon(L)
../_images/41e0bcb0d02e7fa2118a54d9a521f244dfdafa76e754c7965ade82edb3e285ef.png

Question 2 : En adaptant l’instruction de la question précédente, tracer un triangle équilatéral, un pentagone régulier, puis un polygone régulier à \(27\) côtés.

for c in [3, 5, 27]:
    L = [e**(2*k*I*pi/c) for k in range(c) ]
    polygon(L).show()
../_images/8c507a6e5697bdb1790584c442dbee1be45fe340d8d1e9b85b82862c9cfe0a6e.png ../_images/3532444f3c0d5dd2a747a9b34550cff38a23c4e445b6225950305e2fc8fad9ee.png ../_images/9feb58c9a6e1fcd71d138fe84654ba73488e62b313c0f7c1c9ccdbaaad4acdf8.png

Question 3 : Effectuer les instructions suivantes :

  1. Construire T, la liste de points correspondant à un triangle équilatéral de côté \(1\), dont la base est horizontale, et dont le point « en bas à gauche » a pour coordonnées complexes \(z = 1\).

  2. Construire M, la liste des points de T sur lesquels on a appliqué la transformation complexe \(z \mapsto -2z\).

  3. Exécuter les \(2\) instructions suivantes :

figure1 = polygon(T, color="blue") + polygon(M, color="red")
figure1.show()

Quelle transformation géométrique a-t-on opérée sur le triangle bleu ?

T = [1, 2, 1.5 + I*sqrt(3)/2]
M = [-2*z for z in T]
polygon(T, color="blue") + polygon(M, color="red") 
../_images/f0b83cdac93447ef42d128a7a16b4026a89375917a1f8d38590e0f11b22cf954.png

Question 4 (avancée) : Appliquer successivement (11 fois) la transformation complexe \(z \mapsto e^{-i\pi/6} z\) à tous les points de la liste T de la question 2, puis tracer la figure qui contient ces 11 transformations. Quelle transformation géométrique a-t-on opéré ?

c = Color(0.3, 0.5, 0.7)                 # pour créer une couleur moins agressive
PLOT = polygon(T, color=c)               # on stocke un premier triangle dans PLOT
M = [ z for z in T ]
for i in range(11):
    c = c.lighter(0.1)                   # pour éclaircir la couleur c
    M = [exp(-I*pi/6) * m for m in M]
    PLOT += polygon(M, color=c)          # on stocke le nouveau triangle dans PLOT
PLOT.show()                              # on affiche les 12 triangles de PLOT
../_images/919b5b5363eb4ed70a3cf4db7836c8cd6dd3f8e8e7a1fc415d49b1de3a30fd43.png