Apprendre Maple Index du Forum Apprendre Maple
Site dédié au logiciel de calcul formel Maple
 
  Page d'accueilPage d'accueil   FAQFAQ    RechercherRechercher    Liste des MembresListe des Membres    Groupes d'utilisateursGroupes d'utilisateurs 
S'enregistrerS'enregistrer    ProfilProfil   Se connecter pour vérifier ses messages privésSe connecter pour vérifier ses messages privés   ConnexionConnexion 

dichotomie et récursivité

 
Poster un nouveau sujet   Répondre au sujet    Apprendre Maple Index du Forum -> Programmation
Voir le sujet précédent :: Voir le sujet suivant  
Auteur Message
lyna



Inscrit le: 29 Oct 2007
Messages: 15

MessagePosté le: 31 Oct 2007 13:28    Sujet du message: dichotomie et récursivité Répondre en citant

salut, j'ai une procédure a faire.(j'ai donc du mal...).
je ne souhaite pas une solution , mais simplement des indications pour m'aider à la faire.
je dois raisonner par dichotomie pour:

résoudre une équation;pour une fonction f, résoudre f(x)=0.
on se place dans un intervalle [a,b] et on suppose que f(a) .f(b)<0.
on note x1 la solution, cad, f(x1)=0
soit c1 le milieu de l'intervalle [a,b],
si f(a).f(c1)<0 , l'intervalle [a,b] est remplacé par l'intervalle [a1,b1] = [c1,b]
si f(b).f(c1)<0 , l'intervalle [a,b] est remplacé par l'intervalle [a1,b1]=[c1,b]

On recommence l'opération en prenant c2 le milieu de l'intervalle [a1,b1].



je dois donc écrire une procédure "dichotomie" qui prend en entrée une fonction f, des points a et b, et le nombre d'itération n et qui renvoie c(n),lenombre d'itération. j'aurai ensuite à tester la procédure avec la fonction cos(x) , a=0, b=Pi , n=Pi/2.


la première chose que je ne comprends pas c'est le fait de tester la procédure avec une valeur de n définie (n=20); Le nombre d'itération n'est-il pas à déterminer au cours de la procédure? ne correspond t-il pas au nombre de fois qu'oj cherche le mileiu de l'intervalle?

j'ai fais deux tentatives de procédure (en vain):


dichotomie:=proc(f,a,b,n);
f(a);
f(b);
c:=n->(c(n-1)/2);
n:=1;

if f(a)*f(c(n))<0 then
a:=c(n);
b:=b;


elif f(b)*f(c(n))<0 then
a:=a;
b:=c(n);

else print(erreur)
fi;

if n=0 then
RETURN (a+b);
else RETURN c(n);
fi;

end:




et la deuxième :

dichotomie:=proc(f,a,b,n);
f(a);
f(b);
c(n):=(a(n)+b(n))/2;
n:=1;
while (not(c(n)=a(n)) and not(c(n)=b(n))) do
if f(a)*f(c(n))<0 then
a(n)=a(n-1);
b(n)=c(n);

elif f(b)*f(c(n))<0 then
a(n)=c(n);
b(n)=b(n-1);
else print(erreur car f(a) et f(b) ne sont pas de signe différent)
fi;
c(n+1);
od;
print (c(n));
end;



voila, je souhaiterais des indications pour me guider vers une procédure correcte (sans la solution).
Merci..
Revenir en haut de page
Voir le profil de l'utilisateur Envoyer un message privé Envoyer un e-mail
ALS



Inscrit le: 11 Sep 2006
Messages: 647

MessagePosté le: 31 Oct 2007 16:55    Sujet du message: Répondre en citant

Bonjour, le nombre d'itérations est un entier n, et donc ne peut égaler Pi/2. A chaque étape l'intervalle a une longueur divisée par 2, soit (b-a)/2^n pour n itérations.
Le résultat à obtenir est une valeur approchée du zéro souhaité.
Tu trouveras facilement sur le Ouaibe l'algorithme decette méthode.
@+
Revenir en haut de page
Voir le profil de l'utilisateur Envoyer un message privé
lyna



Inscrit le: 29 Oct 2007
Messages: 15

MessagePosté le: 07 Nov 2007 10:07    Sujet du message: Répondre en citant

merci beaucoup, je vais essayer..
Revenir en haut de page
Voir le profil de l'utilisateur Envoyer un message privé Envoyer un e-mail
lyna



Inscrit le: 29 Oct 2007
Messages: 15

MessagePosté le: 07 Nov 2007 11:10    Sujet du message: Répondre en citant

Bonjour, j'ai essayé une nouvelle procédure (qui m'a l'air plutot correcte) mais le problème maintenant c'est que Maple n'arrive pas à évaluer la fonction cos(x) par exemple en certains points.
Je m'explique:
voici ma procédure:

Code:
dichotomie:=proc(f,a,b,n);
f(a);
f(b);
c(k):=(b-a)/2^k;
f(c(k));

for k from 1 to n do
   if f(a)*f(k)<0 then
      a:=k;
      b:=b;
      
      

   elif f(b)*f(k)<0 then
      a:=a;
      b:=k;
      
   
   

fi;
c(k+1);
od;
RETURN (c(n));
end:



et quand je souhaite tester la procédure avec la fonction f(x)=cos x, a=0, b=Pi , n=20 , il y a un problème :


Code:
> dichotomie(x->cos(x),0,Pi,20);
Error, (in dichotomie) cannot determine if this expression is true or false: cos(1) < 0
Revenir en haut de page
Voir le profil de l'utilisateur Envoyer un message privé Envoyer un e-mail
ALS



Inscrit le: 11 Sep 2006
Messages: 647

MessagePosté le: 07 Nov 2007 13:45    Sujet du message: Répondre en citant

Bonjour, mettre des evalf dans vos lignes de test:
if evalf(f(a)*f(k))<0 then
De plus, les instructions comme b:=k vous donneront cette erreur:
Error, (in dichotomie) illegal use of a formal parameter
car Maple interdit que l'on modifie un paramètre formel passé à une procédure. La solution consiste à copier a et b dans des variables locales a1,b1 et à travailler avec a1 et b1.
c(k) et c(k+1) ne marcheront pas non plus
A+
Revenir en haut de page
Voir le profil de l'utilisateur Envoyer un message privé
lyna



Inscrit le: 29 Oct 2007
Messages: 15

MessagePosté le: 11 Nov 2007 17:34    Sujet du message: Répondre en citant

bonjhour et merci pour la réponse.
j'ai suivi tes indications, mais ma procédure ne fonctionne toujours pas...
j espère finir par y arriver..lol
encore merci
Revenir en haut de page
Voir le profil de l'utilisateur Envoyer un message privé Envoyer un e-mail
ALS



Inscrit le: 11 Sep 2006
Messages: 647

MessagePosté le: 11 Nov 2007 19:50    Sujet du message: Répondre en citant

Bonsoir, voici un corrigé possible:

Code:

> dichotomie := proc (f::procedure, a::numeric, b::numeric, eps::numeric)
local a1, b1, k, m;
a1 := a; b1 := b;
k := 0;
while eps < evalf(b1-a1) do
 k := k+1; m := evalf((1/2)*a1+(1/2)*b1);
 if f(m) = 0 then return m
 elif f(m) < 0 then a1 := m else b1 := m
end if
 end do;
print(`nombre d'itérations: ` = k, `  valeur approchée: ` = m)
end proc;

> f:=x->x^3+x-1;
                                       3       
                            f := x -> x  + x - 1

> dichotomie(f,0,1,10^(-9));
       nombre d'itérations:  = 30,   valeur approchée:  = 0.6823278045




A+
Revenir en haut de page
Voir le profil de l'utilisateur Envoyer un message privé
lyna



Inscrit le: 29 Oct 2007
Messages: 15

MessagePosté le: 12 Nov 2007 22:49    Sujet du message: Répondre en citant

merci mais dans cette procédure, le nombre d'itérations n'est pas défini je crois.
alors que dans la mienne on entre déja un entier pour le nombre d'itérations pris en entrée dans la procédue.
Revenir en haut de page
Voir le profil de l'utilisateur Envoyer un message privé Envoyer un e-mail
ALS



Inscrit le: 11 Sep 2006
Messages: 647

MessagePosté le: 13 Nov 2007 8:13    Sujet du message: Répondre en citant

Bonjour,
oui, vous avez raison, je vous laisse adapter en suivant ce modèle, le nb d'itérations étant fourni en paramètre.
A+
Revenir en haut de page
Voir le profil de l'utilisateur Envoyer un message privé
lyna



Inscrit le: 29 Oct 2007
Messages: 15

MessagePosté le: 14 Nov 2007 13:31    Sujet du message: Répondre en citant

bonjour.
je crois que cette fois , c'est la bonne...

voici ma procédure:

>
Code:
 restart;
> dichotomie:=proc(f,a,b,n)
> local a1,b1,k,c;
> a1:=a;
> b1:=b;
> k:=(a1+b1)/2;
>
> for c from 1 to n do
>       if evalf(f(a1)*f(k))<0 then
>             a1:=k;
>
>       elif evalf(f(b1)*f(k))<0 then
>             b1:=k;
>     
>       fi;   

> RETURN (evalf(k));
> od;
> end:
> dichotomie (x->cos(x),0,Pi,20);
                          1.570796327



je trouve bien Pi/2 comme zéro de la fonction, ce qui est bon signe je pense lol.
j'aimerais s'il vous plait que vous me disiez si la procédure vous parait bonne..y aurait-il quelque chose à ajouter?
merci!
Revenir en haut de page
Voir le profil de l'utilisateur Envoyer un message privé Envoyer un e-mail
ALS



Inscrit le: 11 Sep 2006
Messages: 647

MessagePosté le: 14 Nov 2007 13:41    Sujet du message: Répondre en citant

Bonjour, je pense qu'il faut mettre k:=(a1+b1)/2; à l'intérieur de la boucle for, de façon à recalculer k à chaque itération. Sinon, tout me parait correct maintenant, mis à part l'éventualité où f(k) = 0 exactement qui n'a pas été envisagée ici.

> for c from 1 to n do
> k:=(a1+b1)/2;

A+
Revenir en haut de page
Voir le profil de l'utilisateur Envoyer un message privé
lyna



Inscrit le: 29 Oct 2007
Messages: 15

MessagePosté le: 14 Nov 2007 13:46    Sujet du message: Répondre en citant

"l'éventualité où f(k) = 0 exactement "?
mais on a bien f(Pi/2) =0 exactement...
Revenir en haut de page
Voir le profil de l'utilisateur Envoyer un message privé Envoyer un e-mail
ALS



Inscrit le: 11 Sep 2006
Messages: 647

MessagePosté le: 15 Nov 2007 9:01    Sujet du message: Répondre en citant

Bonjour, il existe des cas où on peut tomber sur k qui vaut exactement la racine recherchée :exemple si la racine vaut 1/8 et que l'on part de 0 et 1: on aurait successivement k = 1/2, k =1/4 pour tomber sur k=1/8 donc f(k)=0 et on sort de la procédure.
A+
Revenir en haut de page
Voir le profil de l'utilisateur Envoyer un message privé
lyna



Inscrit le: 29 Oct 2007
Messages: 15

MessagePosté le: 15 Nov 2007 9:57    Sujet du message: Répondre en citant

bonjour.
oui ok.
je voulais vous remercier pour toute votre aide depuis le début...
bonne journée
Revenir en haut de page
Voir le profil de l'utilisateur Envoyer un message privé Envoyer un e-mail
Montrer les messages depuis:   
Poster un nouveau sujet   Répondre au sujet    Apprendre Maple Index du Forum -> Programmation Toutes les heures sont au format GMT + 2 Heures
Page 1 sur 1

 
Sauter vers:  
Vous ne pouvez pas poster de nouveaux sujets dans ce forum
Vous ne pouvez pas répondre aux sujets dans ce forum
Vous ne pouvez pas éditer vos messages dans ce forum
Vous ne pouvez pas supprimer vos messages dans ce forum
Vous ne pouvez pas voter dans les sondages de ce forum


phpBB

Développé par phpBB © 2001, 2006 phpBB Group
Traduction par : phpBB-fr.com


Apprendre Maple - ©  - Alain Le Stang - Navigation optimisée pour une résolution 1024 x 768.