Feuille d’exercices 6#
Objectifs
Nombres réels
Notion de précision
Affichage graphique
Exercice 1. Manipulation de nombre flottant avec une précision donnée#
Question 1 : Effectuer successivement les instructions suivantes.
Stocker dans une variable
xle rationnel \(1/7\).Stocker dans une variable
R1le corps des réels à une précision de \(1\) bit.Quelle puissance de \(2\) (éventuellement d’exposant négatif) est la plus proche de \(1/7\) ? Effectuer une coercion de
xdansR1, puis vérifier votre réponse.Stocker dans une variable
R3le corps des réels à une précision de \(3\) bits.Effectuer une coercion de
xdansR3, puis retrouver la mantisse et l’exposant correspondant. On pourra également s’aider de la méthode.sign_mantissa_exponent().En effectuant une coercion de
xdans une structure appropriée, donner les \(100\) premières décimales de \(1/7\).
x = 1/7
R1 = RealField(1)
La puissance de \(2\) la plus proche de \(1/7\) est \(2^{-3} = 1/8\). Vérifions-le :
R1(x) == 1/8
True
R3 = RealField(3)
y = R3(x)
y.sign_mantissa_exponent()
(1, 5, -5)
La mantisse vaut \(5\) et l’exposant \(-5\). En effet, le nombre représenté sur \(3\) bits le plus proche de \(17\) est \(\frac{5}{32} = 2^{-3} + 2^{-5} = 5 \times 2^{-5}\). On le vérifie une nouvelle fois :
print(y)
print(y == 5/32)
0.16
True
Enfin, les \(100\) premières décimales de \(1/7\) sont :
nombres_bits = ceil(100*log(10,2))
print(RealField(nombres_bits)(x))
0.142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857142857143
Exercice 2. Affichage graphique simple#
Question 1 : Tracer sur un même graphique les fonctions cosinus (en bleu) et sinus (en rouge), entre \(0\) et \(4\pi\).
plot(cos, [0, 4*pi], color="blue") + plot(sin, [0, 4*pi], color="red")
Question 2 :
Tracer la fonction tangente entre \(-\pi\) et \(\pi\).
Puis, essayer de rendre le tracé plus « représentatif » en imposant une valeur maximale et minimale à l’ordonnée.
Pourquoi pensez-vous qu’il y a des droites verticales ? Les retirer en ajoutant l’argument optionnel
detect_poles=Truedans la fonctionplot().
plot(tan, [-pi, pi])
plot(tan, [-pi, pi], ymax = 10, ymin = -10)
plot(tan, [-pi, pi], ymax = 10, ymin = -10, detect_poles=True)
Exercice 3. Série harmonique#
On considère la suite \((H_n)_{n \ge 1}\) définie comme : \(H_n = \sum_{i=1}^n \frac{1}{n}\). Cette suite est appelée « série harmonique ».
Question 1 : Écrire une fonction calcule_H(n) qui prend en entrée un entier naturel n et qui retourne le terme \(H_n\).
def H(n):
res = 0
for i in range(1, n+1):
res += 1/i
return res
print(H(3))
11/6
Question 2 : Tracer sur un même graphique :
les \(100\) premiers termes de la suite \(H_n\),
la fonction \(\ln(x)\) pour \(x \in [1, 100]\).
Pour tracer les termes de la série harmonique, on rappelle qu’on peut utiliser la fonction points(L) qui prend en entrée une liste de points de la forme \([ (x_1, y_1), \dots, (x_k, y_k) ]\) , et qui retourne un objet graphique (comme le ferait plot) représentant tous les points de coordoonées \((x_i, y_i)\) de la liste.
points([[i, H(i)] for i in range(100)]) + plot(ln, [1, 100], color="red")
Question 3 : La différence \(H_n - \ln(n)\) semble converger vers une constante. La calculer approximativement. Pour cela, on pourra calculer des termes de \(u_n := H_n - \ln(n)\) jusqu’à ce que deux termes consécutifs de la suite \((u_n)\) soit distants de moins de \(10^{-8}\).
Indication supplémentaire : comme la convergence est lente, on pourra essayer de :
reformuler la valeur de \(u_{n+1}-u_n\) pour éviter de calculer des sommes
calculer les \(u_{n+1}-u_n\) avec des ordre \(n\) allant de \(100\) en \(100\) plutôt que de \(1\) et \(1\)
Puis, comparer la valeur obtenue à l’objet euler_gamma de Sagemath.
def calcule_constante():
n = 2
eps = 10**(-8)
e = 1
while abs(e) > eps :
# e = H(n) - ln(n) - H(n-1) + ln(n-1)
e = 1/n - ln(n/(n-1))
n += 1
print("n =", n)
return H(n)-ln(n)
g = calcule_constante()
print(float(g))
print(float(euler_gamma))
n = 7073
0.5772863545972928
0.5772156649015329
Exercice 4. Produit de Wallis et une mauvaise approximation rationnelle de \(\pi\)#
En 1656, Wallis a démontré que
Nous allons utiliser cette formule pour obtenir une approximation rationnelle (mais peu efficace) de \(\pi\).
Question 1 : Écrire une fonction produit_wallis(k) qui prend en entrée un entier strictement positif k, et qui retourne le produit
Vérifier ensuite que \(P_1 = \frac{4}{3}\) et que \(P_6 = \frac{1048576}{693693}\).
def produit_wallis(k):
res = 1
for n in range(1, k+1):
res *= (4*n**2)/(4*n**2-1)
return res
print(produit_wallis(1))
print(produit_wallis(6))
4/3
1048576/693693
Question 2 : Afficher le nombre flottant associé à \(2 P_{100}\), puis vérifier qu’il a au moins une décimale en commun avec \(\pi\).
print(RealField()(2*produit_wallis(100)))
3.13378749062816
Question 3 : Quelle est la plus petite valeur de \(k\) pour laquelle les nombres \(2 P_k\) et \(\pi\) ont au moins \(3\) décimales en commun ? Quel est alors le nombre de chiffres du dénominateur \(d\) de la fraction \(2 P_k\) (calculer la partie entière supérieure de \(\log_{10}(d)\) pour obtenir cela) ?
k = 1
w = produit_wallis(k)
while abs(pi - 2*w) > 10**(-3):
k += 1
w = produit_wallis(k)
print(k)
print("Le dénominateur a", ceil(log(w.denominator(), 10)), "chiffres décimaux")
785
Le dénominateur a 943 chiffres décimaux
Remarque : on peut s’épargner des calculs répétés avec les instructions suivantes :
k = 0
w = 1
seuil = 10**(-3)
while abs(pi - 2*w) > seuil:
k += 1
t = 4*k**2
w *= t/(t-1)
print(k)
print("Le dénominateur a", ceil(log(w.denominator(), 10)), "chiffres décimaux")
785
Le dénominateur a 943 chiffres décimaux
Remarque : Cette manière de calculer les décimales de \(\pi\) est donc très peu efficace.