Inscription / Connexion Nouveau Sujet
Niveau Prepa (autre)
Partager :

python

Posté par
nullptr19
20-01-21 à 03:10

Bonjour à toutes à tous .

je souhaiterai mettre en machine le test de primalité de Mersenne .

Petit rappel du cours.

un nombre de Mersenne est un entier de la forme M_p=2^p-1 avec p premier .

Mp est premier ssi Mp est divisible par Sp ou la suite (s_n)_n est définie par :

S_2=4 et S_{k+1}=S^2_k-2

alors j'ai opté pour découper ce programme en trois fonctions , notez par ailleurs que , la fonction "primalite"  qui est un test de primalité naïve , est déjà belle et bien programmé , mais si je prend des p de plus en plus grand je ferai appel aux test probabiliste éventuellement , mais l'idée serait de comprendre d'abord comment ça marche de manière simple .

voici ce que je propose :

def NombreMersenne(p):
    Mp=2**p-1
    
    if primalite(p) is True:
        return Mp
    else :
        return False

def SuiteMersen(p):
    s=4
    for i in range (3, p+1):
        s=s**2-2
    return (s)

def PrimaliteMersen(p):
    while primalite(p) is True:
        if (SuiteMersen(p)%NombreMersenne(p)) == 0:
            return True
        else:
            return False
    
    return "erreur: rentrer un nombre premier"


ce programme marche pour des nombres de Mersenne avec p=3,5,7,13

après ça ne rame , aussi pour p= 2 je rencontre des difficulté ,

merci pour vos retours

Posté par
flight
re : python 20-01-21 à 09:52


Salut

ce serait pas plutot  "Mp est premier si et seulement si Mp divise Sp"

Posté par
Zormuche
re : python 20-01-21 à 09:54

Bonjour

Je ne comprends pas comment on peut conclure que Mp est premier en montrant qu'il est divisible par quelque chose, ni comment Mp peut être divisible par sp qui est manifestement plus grand que Mp

Posté par
flight
re : python 20-01-21 à 09:58

pour p =2 je pense qu'il faut créer une exception dans tes lignes de code

Posté par
nullptr19
re : python 20-01-21 à 10:10

Bonjour flight mais la fonction NombreMersenne(p) me revoit Mp  . et la fonction SuiteMersenne(p) me renvoi Sp c'est la raison pour laquelle comme condition de primalité j'ai écris  :

if (SuiteMersen(p)%NombreMersenne(p)) == 0:

et pour le cas p=2 oui je pense qu'une petite condition fera l'affaire , j'y reviendrai après mon cours .

Posté par
nullptr19
re : python 20-01-21 à 13:36

flight @ 20-01-2021 à 09:52


Salut

ce serait pas plutot  "Mp est premier si et seulement si Mp divise Sp"


si mais en machine cela cause t'il un pb ?

Posté par
nullptr19
re : python 20-01-21 à 13:38

Zormuche @ 20-01-2021 à 09:54

Bonjour

Je ne comprends pas comment on peut conclure que Mp est premier en montrant qu'il est divisible par quelque chose, ni comment Mp peut être divisible par sp qui est manifestement plus grand que Mp


je n'ai fait recopier la proposition du cours sur les nombres de Mersenne et c'est ce que j'ai essayé de traduire en machine

Posté par
flight
re : python 20-01-21 à 14:08

En machine on écrira Sp mod Mp =0

Posté par
Zormuche
re : python 20-01-21 à 14:41

nullptr19 @ 20-01-2021 à 13:38

Zormuche @ 20-01-2021 à 09:54

Bonjour

Je ne comprends pas comment on peut conclure que Mp est premier en montrant qu'il est divisible par quelque chose, ni comment Mp peut être divisible par sp qui est manifestement plus grand que Mp


je n'ai fait recopier la proposition du cours sur les nombres de Mersenne et c'est ce que j'ai essayé de traduire en machine
oui mais tu avais fait une faute de frappe, c'est pour ça

Posté par
nullptr19
re : python 20-01-21 à 17:28

Bonsoir Zormuche une faute de frappe ? je ne vous suis  pas , à quel niveau ?

Posté par
nullptr19
re : python 20-01-21 à 17:30

flight @ 20-01-2021 à 14:08

En machine on écrira Sp mod Mp =0


mais c'est ce que j'ai traduis , avec les deux fonctions SuiteMersen(p) et NombreMersenne(p) qui me renvoient respectivement Sp et Mp , y'aurait t-il un problème à ce niveau ?

Posté par
verdurin
re : python 20-01-21 à 19:12

Bonsoir,
la fonction SuiteMersen() croît très vite.
Par exemple SuiteMersen(17) à presque dix-neuf mille chiffres en base dix.

Il me semblerait judicieux de la calculer modulo Mp.

Je me demande à quoi sert la ligne

while primalite(p) is True
dans la fonction PrimaliteMersen() en effet primalite(p) est une constante car p ne change pas dans la boucle.

Dans la fonction NombreMersenne(p) il me semble inutile de calculer la valeur avant d'avoir vérifié que p est premier.
Quelque chose du genre
def NombreMersenne(p):
    if primalite(p) is True :
        return 2**p-1
    else :
        return False
me semble plus logique.

Posté par
nullptr19
re : python 20-01-21 à 20:28

verdurin effectivement il me semble que mes vieux démons du code précédant ne m'ont pas lâché , je pourrai bien me passer du while avec un if , la condition "if" suffit en effet , mais rassurez moi que j'ai bien besoin de la fonction primalité , au moins pour vérifier si p est premier , et pour votre remarque , effectivement pour p=31 ça me donne un nombre avec une longueur allant à plus de 100 chiffre c'est embêtant pour la machine avec le code que je propose   .

je reviens vers vous je revois le code , merci

Posté par
nullptr19
re : python 20-01-21 à 20:38

verdurin @ 20-01-2021 à 19:12

Bonsoir,
la fonction SuiteMersen() croît très vite.
Par exemple SuiteMersen(17) à presque dix-neuf mille chiffres en base dix.

Il me semblerait judicieux de la calculer modulo Mp.

Je me demande à quoi sert la ligne
while primalite(p) is True
dans la fonction PrimaliteMersen() en effet primalite(p) est une constante car p ne change pas dans la boucle.

Dans la fonction NombreMersenne(p) il me semble inutile de calculer la valeur avant d'avoir vérifié que p est premier.
Quelque chose du genre
def NombreMersenne(p):
    if primalite(p) is True :
        return 2**p-1
    else :
        return False
me semble plus logique.


ah oui la mème erreur qu'au précédant code , en fait c'est plutôt un if qui peut simplement faire l' affaire : je revois le code et je reviens vers vous , mais vous me rassurez quand même que on a nécessairement besoin de la fonction primalité au moins pour vérifier que p est premier .

bon je m'y met et je reviens vers vous , merci

Posté par
verdurin
re : python 20-01-21 à 21:04

Sans aucun calcul je dirais que c'est le nombre de chiffres du nombre de chiffres de S31 qui a 100 chiffres.
En décimal SuiteMersen(19) s'écrit avec  74\,967 chiffres et il en faut 1\,199\,461 pour  SuiteMersen(23).

Il faut calculer Sp modulo Mp si on veut éviter les problèmes de débordement de capacité.
Qui arrivent même pour de « petites » valeurs de p.

Posté par
nullptr19
re : python 20-01-21 à 21:05

flight @ 20-01-2021 à 09:52


Salut

ce serait pas plutôt  "Mp est premier si et seulement si Mp divise Sp"


oui c'est ça et non divisible , merci

Posté par
verdurin
re : python 20-01-21 à 21:55

Une esquisse de fonction


def PrimaliteMersenne(p) :
# on suppose que p est un entier strictement positif,
# on peut éventuellement vérifier que c'est bien le cas
# et renvoyer une erreur si ce n'est pas le cas

    si p n'est pas premier :
        retourne Faux

    # on est maintenant dans le cas où p est premier

    si p vaut 2 retourne Vrai 
    # p=2 est un cas particulier

    Mp=2**p-1 
    
    # on calcule Sp modulo Mp
    # si on trouve 0 Mp divise Sp et Mp est premier sinon il ne l'est pas
    s=4%Mp
    for i in range (3, p+1):
        s=(s**2-2)%Mp
    si s vaut 0 :
        retourne Vrai
    sinon :
        retourne Faux

Posté par
nullptr19
re : python 21-01-21 à 10:47

Bonjour .

verdurin J'ai parfaitement compris ton idée . Sauf que en le traduisant en machine j'ai en effet pris en compte le fait que de distinguer deux condition ( deux cas) .

1. p n'est pas premier , la fonction me renvoie False

2. sinon ( cas p est premier) , c'est sous cette condition que je vérifie la condition de primalité de Mersenne .

sauf que en machine en essayant de traduire , ça me renvoie toujours pas les bons résultats , voici ce que j'ai fait :

def PrimaliteMersen(p):
    if p < 0 :
        return "erreur"
    if primalite(p) is False:
        return False
    else:
        if p==2:
            return True
        Mp=2**p -1
        s=4%Mp
    for i in range (3,p+1):
        s=(s**2-2)%Mp
    if s==0:
        return True
    else :
        return False

Posté par
verdurin
re : python 21-01-21 à 15:31

Si ce que tu as posté est exactement ton code, il est mal indenté.
Tout ce qui suit

    if primalite(p) is False:
        return False
    else:
est dans le "else".
Le quel "else" est inutile, puisque l'on sort de la fonction si  "primalite(p) is False"

En recopiant ta fonction (sans le "else" ) j'obtient
>>> PrimaliteMersen(3)
True
>>> PrimaliteMersen(4)
False
>>> PrimaliteMersen(11)
False
>>> PrimaliteMersen(61)
True
>>> PrimaliteMersen(67)
False
>>> PrimaliteMersen(127)
True
>>> PrimaliteMersen(199)
False
>>> PrimaliteMersen(-3)
'erreur'
>>> PrimaliteMersen(2.5)
False
pour le dernier résultat ma fonction primalité exclu les valeurs non entières.

Posté par
nullptr19
re : python 21-01-21 à 17:39

verdurin j'avais des doutes sur l'indentation surtout si ça avait un sens de mettre le reste du programme dans else , à priori ça na pas de sens ici(et dalleur je ne sais pas si ça un sens en général) ,effectivement vu que ce son des booléens que va renvoyer la fonction , si on passe la condition du premier if (qui renvoie False ) alors on n'est sur que la condition que on à bien un True . en rectifiant en prenant en compte le fait de pas prendre en compte des flottants , mon programme me donne la même chose que toi , sauf que pour p=67 ça me renvoie en False je ne sais pas si c'est normal car pour p=67 , Mp est sensé être

bref voici ce que ca donne après rectification premier , non ?

def PrimaliteMersen(p):
    if p==float(p):
        return False
    if p < 0 :
        return "erreur"
    if primalite(p) is False:
        return False
    if p==2:
        return True
    Mp=2**p -1
    s=4%Mp
    for i in range (3,p+1):
        s=(s**2-2)%Mp
    if s==0:
        return True
    else :
        return False

Posté par
nullptr19
re : python 21-01-21 à 17:40

Mp sensé être premier voulais je dire

Posté par
verdurin
re : python 21-01-21 à 18:53

"p==float(p)" est vrai pour tout les entiers.
Donc ta fonction retourne toujours False.

Pour tester si p est un entier j'utilise "isinstance(p,int)"

Je crois que tu peux te passer de ce test, de même que du test p<0, au moins dans un premier temps.

Sinon j'ai la même fonction et elle donne des résultats justes, au moins pour les petites valeurs de p.
J'ai vérifié ici et là .
Au passage 267-1 n'est pas premier.

Posté par
nullptr19
re : python 21-01-21 à 19:04

effectivement j'aurai du penser à utiliser "Isinstance" avec float ça prend tout le monde pour un entier par exemple la machine peut l'interpréter comme  2.0(sauf erreur de ma part) , j'avoue que le False est tout le temps vérifié , du coup je vais pas compliquer d'avantage je me passe de ça pour le moment en gros je pense pas que ce soit très nécessaire par la suite je vais mettre des petites conditions pour gérer ces petites erreurs , du coup ça marche , il doit y avoir une coquille dans mon cours car il est mentionne que pour p =67 , Mp est premier ,je vais me renseigner auprès de mon professeur dans ce cas .

Merci verdurin

Posté par
verdurin
re : python 21-01-21 à 20:34

2^{67}-1=193\,707\,721\times761\,838\,257\,287



Vous devez être membre accéder à ce service...

Pas encore inscrit ?

1 compte par personne, multi-compte interdit !

Ou identifiez-vous :


Rester sur la page

Inscription gratuite

Fiches en rapport

parmi 1675 fiches de maths

Désolé, votre version d'Internet Explorer est plus que périmée ! Merci de le mettre à jour ou de télécharger Firefox ou Google Chrome pour utiliser le site. Votre ordinateur vous remerciera !