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