en pdf

Transcription

en pdf
L3AlgebreEffectiveTP1Cor
Frederic Eyssette
lundi 14 septembre 2015
L3 Maths 2015-2016 Algèbre Effective
TP1 : Pgcds d’entiers
Pour commencer on va modifier deux versions du calcul du pgcd de deux entiers, une version récursive
def PgcdRec (a , b ) :
if b ==0 : return ( a )
else : return ( PgcdRec (b , a % b ) )
et une version itérative
def PgcdIter (a , b ) :
while b !=0 : r = a % b ; a = b ; b = r
return ( a )
Remarquer le test d’égalité == , d’inégalité !=, l’affectation = , le reste de la division euclidienne % N’oubliez
pas d’évaluer (Maj-entrée ou Run) avant d’utiliser
PgcdRec (132 ,105)
PgcdIter (132 ,105)
PgcdRec (3443 ,55) , PgcdIter (3443 ,55)
Evidemment la fonction existe dans Sage
gcd (3443 ,55)
Avoir de l’aide en ligne est important, on ne peut pas mémoriser les milliers de fonctions de ce genre de
logiciel. Exécuter les lignes suivantes.
gcd ?
help ()
help ( gcd )
Pour savoir ce qu’un objet accepte comme fonctions taper l’objet suivi d’un . puis la touche tab Faire tab
dans la ligne ci dessous.
132.
1
Exercice 1 Modifier les fonctions PgcdRec et PgcdIter pour qu’elles affichent les restes calculés comme cidessous. Utiliser la fonction print.
def PgcdRecVoir (a , b ) :
if b ==0 : return ( a )
else : r = a % b ; print ( r ) ; return ( PgcdRecVoir (b , r ) )
PgcdRecVoir (132 ,105)
27
24
3
0
3
def PgcdIterVoir (a , b ) :
while b !=0 : r = a % b ; print ( r ) ; a = b ; b = r
return ( a )
PgcdIterVoir (132 ,105)
27
24
3
0
3
Exercice 2 Modifier les fonctions PgcdRec et PgcdIter pour qu’elles construisent la suite d’Euclide formée
des nombres de départ puis de la suite des restes calculés comme ci-dessous. Vous aurez besoin de la fonction
append qui ajoute un élément à une liste ou de la fonction + qui concatène des listes. La fonction append
modifie la liste.
L =[1 ,2 ,3 ,4]; L
[1, 2, 3, 4]
L . append (10) ; L
[1, 2, 3, 4, 10]
L +[6 ,7 ,8]; L
[1, 2, 3, 4, 10, 6, 7, 8]
[1, 2, 3, 4, 10]
def PgcdRecSuite (a , b ) :
L =[ a ];
if b ==0 : return ([ a ,0])
else : r = a % b ; return ( L + PgcdRecSuite (b , r ) )
PgcdRecSuite (132 ,105)
[132, 105, 27, 24, 3, 0]
def PgcdIterSuite (a , b ) :
L =[ a , b ];
while b !=0 : r = a % b ; L . append ( r ) ; a = b ; b = r
return ( L )
2
PgcdIterSuite (132 ,105)
[132, 105, 27, 24, 3, 0]
Exercice 3 Modifier les fonctions PgcdRec et PgcdIter pour qu’elles calculent le nombre de divisions effectuées
lors de l’algorithme.
def PgcdIterCompte (a , b ) :
c =0;
while b !=0 : r = a % b ; a = b ; b = r ; c = c +1
return ( c )
PgcdIterCompte (132 ,105)
4
def PgcdRecCompte (a ,b , c ) :
if b ==0 : return ( c )
else : return ( PgcdRecCompte (b , a %b , c +1) )
PgcdRecCompte (132 ,105 ,0)
4
Calculer le nombre de divisions dans les cas suivants et commenter :
PgcdIterCompte ( 8 7 4 8 9 4 5 6 4 4 5 4 1 4 1 4 5 6 5 1 4 1 7 , 8 7 4 8 9 4 5 6 4 4 5 4 1 4 1 4 5 6 5 1 4 1 6 )
2
PgcdIterCompte ( 8 7 4 8 9 4 5 6 4 4 5 4 1 4 1 4 5 6 5 1 4 1 7 , 6 7 4 8 9 4 5 6 4 4 5 4 1 4 1 4 5 6 5 1 4 1 7 )
42
On voit que le nombre de divisions est très variable pour des nombres de même taille, mais qu’il est petit par
rapport à la taille des nombres (de l’ordre du nombre de chiffres ?). On fera un commentaire plus détaillé
en cours.
Exercice 4 Modifier la fonction PgcdIter pour qu’elle rende le pgcd et les coefficients de Bézout. Vous aurez
besoin de l’opérateur // qui donne le quotient de la division euclidienne.
def BezoutIter (a , b ) :
u0 =1; v0 =0; u1 =0; v1 =1;
while b !=0 :
q = a // b ; r = a % b ; u2 = u0 - q * u1 ; v2 = v0 - q * v1 ;
u0 = u1 ; v0 = v1 ; u1 = u2 ; v1 = v2 ; a = b ; b = r
return (a , u0 , v0 )
BezoutIter (132 ,105)
(3, 4, -5)
BezoutIter (1870 ,242)
(22, -4, 31)
Comme on l’a vu en td. Même question avec PgcdRec.
3
def BezoutRec (a ,b , u0 , v0 , u1 , v1 ) :
if b ==0 : return (a , u0 , v0 )
else : q = a // b ; u2 = u0 - q * u1 ; v2 = v0 - q * v1 ; return ( BezoutRec (b , a %b , u1 , v1 , u2 ,\
v2 ) )
BezoutRec (1870 ,242 ,1 ,0 ,0 ,1)
(22, -4, 31)
Comme l’initialisation de u0, v0, u1, v1 est lourde et peut être source d’erreur on définit une fonction
auxiliaire qui appelle BezoutRec correctement initialisé.
def BezoutAux (a , b ) :
return ( BezoutRec (a ,b ,1 ,0 ,0 ,1) )
BezoutAux (1870 ,242)
(22, -4, 31)
Evidemment cette fonction existe dans Sage :
xgcd ?
4

Documents pareils