Fonction récursive R

Fonction récursive R - Divers - Programmation

Marsh Posté le 29-07-2013 à 14:40:40    

Bonjour à toutes et à tous,
je suis un grand débutant dans la programmation R, et rien de bien impressionnant ... je me suis planté. Pour vous contextualiser un peu l'idée, j'essaye de créer une fonction récursive sous R qui s'appelle (en faisant un échantillon "de lui-même" ) tant que le compteur n'est pas arrivé à un certain niveau. Une fois cette chose faite, la fonction appelle une autre fonction offrant un résultat. LE but d'utiliser R est donc ici pour moi d'éviter de faire des boucles imbriquées de nombre variable, en passant par la vectorisation.
Au final, si n = 1, alors le résultat de Last sort ; si n=2 un échantillon de m Last sort et on en fait une moyenne ; si n=3 un échantillon de m Appel (constitué de moyennes de m Appel "plus profonds" ) sort et on en fait une moyenne ......
 
J'espère avoir était clair en exposant mon problème, car je ne trouve à ce jour pas de solution. Je vous joint mon code juste en-dessous.
 

Code :
  1. Appel<-function(i,m,n,a,b)
  2. {
  3. i=i+1
  4. if (i=n) {
  5. z=Last(m,a,b,n)
  6. }
  7. else {
  8. x=replicate(m, Appel(i,m,n,a,b))
  9. y=mean(x)
  10. }
  11. return(y)
  12. }


 
Merci d'avance

Reply

Marsh Posté le 29-07-2013 à 14:40:40   

Reply

Marsh Posté le 29-07-2013 à 16:36:39    

Je ne connais pas R, mais ca me surprend que ce soit le même opérateur pour l'affectation et l'assignation. Tu pourrais commencer à vérifier de ce côté là.
 
Quand i vaut n (je te recommanderais de tester en >= tout de même) tu assignes une valeur à z mais pas à y, or, plus bas, c'est toujours y que ta fonction retourne. Ca semble faux.


---------------
last.fm
Reply

Marsh Posté le 29-07-2013 à 17:31:25    

En effet, ces deux points étaient à voir. J'ai entre deux changé la valeur de y pour retourner toujours z, et le "debugger" de R m'ayant dit qu'il y a un problème du côté de l'indice, j'ai inverser les deux "contenus" et marqué i+1<n.
Le code est à présent (parce que déjà mieux je pense) ainsi :
 

Code :
  1. Appel<-function(i,m,n,a,b)
  2. {
  3. if (i+1<n){
  4. x=replicate(m, Appel(i+1,m,n,a,b))
  5. y=mean(x)
  6. }
  7. else{
  8. z=Last(m,a,b,n)
  9. }
  10. return(z)
  11. }

Reply

Marsh Posté le 29-07-2013 à 18:16:29    

rockr a écrit :

En effet, ces deux points étaient à voir. J'ai entre deux changé la valeur de y pour retourner toujours z, et le "debugger" de R m'ayant dit qu'il y a un problème du côté de l'indice, j'ai inverser les deux "contenus" et marqué i+1<n.
Le code est à présent (parce que déjà mieux je pense) ainsi :
 

Code :
  1. Appel<-function(i,m,n,a,b)
  2. {
  3. if (i+1<n){
  4. x=replicate(m, Appel(i+1,m,n,a,b))
  5. y=mean(x)
  6. }
  7. else{
  8. z=Last(m,a,b,n)
  9. }
  10. return(z)
  11. }



 
Après un coup d'oeil succint à la doc du langage :
 

Code :
  1. Appel<-function( i, m, n, a, b )
  2. {
  3.   if ( i < n )
  4.   {
  5.     x <- replicate( m, Appel( i + 1, m, n, a, b ) )
  6.     y <- mean( x )
  7.   }
  8.   else
  9.   {
  10.     z <- Last( m, a, b, n )
  11.   }
  12.   return(z)
  13. }


 
Cela dit, j'aimerais bien savoir ce que font mean, replicate et Last dans le détail. J'imagine à tout hasard que replicate est une fonction qui va appliquer une function à un ensemble d'élément et retourner l'ensemble des résultats (sinon, mean qui semble être censé faire la moyenne n'a pas de sens). Le problème dans ce cas, c'est que tu fournis à replicate le résultat de ton appel récursif suivant, ce qui ne semble pas être ce que tu veux, non ?
 
Je ne comprends pas pourquoi maintenant, tu assignes une valeur à y pour retourner z ...


Message édité par theshockwave le 29-07-2013 à 18:17:36

---------------
last.fm
Reply

Marsh Posté le 29-07-2013 à 19:11:13    

J'ai encore oublié de recopier comme il le faut .......... mais sinon c'est bien z=mean(x).
Concernant les fonctions :  
     -la fonction mean() renvoie la moyenne d'un ensemble de données (mean(x) où x est un vecteur est donc la moyenne des éléments du vecteur)
     -la fonction replicate() répète m fois la fonction spécifiée (ici Appel() ) et fournit les résultats dans un vecteur de dimension m
     -la fonction Last() est une fonction que j'ai moi-même créé (qui est testée et donc fonctionne) et renvoie une valeur aléatoire
 
En effet, je fournis ici à replicate() le résultat de mon appel récursif suivant, et c'est ce que je cherche à faire. De manière peut-être plus synthétique, j'essaye de faire quelque chose comme  
    mean(replicate(m,mean(replicate(......(m,replicate(m,Last(m,a,b,n)))))))))....))))

Reply

Marsh Posté le 30-07-2013 à 11:27:14    

rockr a écrit :

J'ai encore oublié de recopier comme il le faut .......... mais sinon c'est bien z=mean(x).
Concernant les fonctions :  
     -la fonction mean() renvoie la moyenne d'un ensemble de données (mean(x) où x est un vecteur est donc la moyenne des éléments du vecteur)
     -la fonction replicate() répète m fois la fonction spécifiée (ici Appel() ) et fournit les résultats dans un vecteur de dimension m
     -la fonction Last() est une fonction que j'ai moi-même créé (qui est testée et donc fonctionne) et renvoie une valeur aléatoire
 
En effet, je fournis ici à replicate() le résultat de mon appel récursif suivant, et c'est ce que je cherche à faire. De manière peut-être plus synthétique, j'essaye de faire quelque chose comme  
    mean(replicate(m,mean(replicate(......(m,replicate(m,Last(m,a,b,n)))))))))....))))


 
donc, techniquement, de ce que je comprends, tu veux dupliquer un élément sélectionné par Last() sur l'ensemble de ton conteneur (donc mettre tout à la même valeur) puis faire la moyenne de ce conteneur (donc récupérer exactement la même valeur), retourner cette valeur pour que l'appel précédent fasse exactement la même chose ? [:pingouino]


---------------
last.fm
Reply

Marsh Posté le 30-07-2013 à 17:32:53    

Au fait, on n'a toujours pas vu les messages d'erreur que tu obtiens, peut-être que ca pourrait nous aider à t'aider ? :)


---------------
last.fm
Reply

Marsh Posté le 30-07-2013 à 20:16:26    

Au final, ça revient à faire :

Code :
  1. mean(m, ..., m, Last(a,b,m,n))


m,...,m étant un vecteur de (n - i_initial - 1) éléments
 
donc au final ça fait :

Code :
  1. (m * (n - i_initial -1 ) + Last(a,b,m,n))/(n - i_initial)


 
C'est pas un peu compliqué la récursion sur un jeu de donnée non récursif/algo non récursif (type suite) ?
 
J'ai rien compris ?
 
[Edit]
 
Oui j'ai rien compris :pt1cable: c'est pas le m qui est ajouté à la liste, mais le résultat de la moyenne
 
Mais alors  

Code :
  1. x<-replicate(m,Appel(xxxx))
  2. z<-mean(x)


 
c'est strictement équivalent à  

Code :
  1. x<- (m *Appel(xxxx))/m // équivalent à x<-Appel(xxx)


Puisque l'on fait un vecteur de m élements contenant Appel(xxx) que l'on moyenne
 
Donc au final l'algo donne Appel(i,m,n,a,b) = Last(m,n,a,b) non ?

Message cité 1 fois
Message édité par dreameddeath le 30-07-2013 à 20:26:03
Reply

Marsh Posté le 30-07-2013 à 21:36:50    

dreameddeath a écrit :

Au final, ça revient à faire :
C'est pas un peu compliqué la récursion sur un jeu de donnée non récursif/algo non récursif (type suite) ?
 
J'ai rien compris ?


 
Techniquement, c'est pas aberrant d'utiliser de la récurisvité pour traiter des listes plates. dès que tu utilises un langage fonctionnel, tu te retrouves à faire ca massivement. C'est simplement moins commun dans des langage impératifs.
 

dreameddeath a écrit :

Au final, ça revient à faire :
Mais alors  

Code :
  1. x<-replicate(m,Appel(xxxx))
  2. z<-mean(x)


 
c'est strictement équivalent à  

Code :
  1. x<- (m *Appel(xxxx))/m // équivalent à x<-Appel(xxx)


Puisque l'on fait un vecteur de m élements contenant Appel(xxx) que l'on moyenne
 
Donc au final l'algo donne Appel(i,m,n,a,b) = Last(m,n,a,b) non ?


 
Non, c'est plutôt équivalent à

Code :
  1. x<-Appel(...)


de ce que j'en ai compris. La multiplication/division par m (alors que, visiblement, m est un conteneur) n'a pas trop de sens.


---------------
last.fm
Reply

Marsh Posté le 31-07-2013 à 11:26:41    

pour le coup de la division/multiplication par m je suis parti de la phrase

Citation :


la fonction replicate() répète m fois la fonction spécifiée (ici Appel() ) et fournit les résultats dans un vecteur de dimension m  


 
Pour le coup des liste plates je suis d'accord pour utiliser la récursivité, mais je ne vois pas de liste plate ici. En effet :
- quand on appelle récursivement, on ne joue pas sur une liste
- ni le "retour" de la récursion ne "construit" de liste (car z semble être un entier)
 
Donc pour moi m n'est pas un conteneur

Reply

Marsh Posté le 31-07-2013 à 11:26:41   

Reply

Marsh Posté le 31-07-2013 à 11:40:31    

dreameddeath a écrit :

pour le coup de la division/multiplication par m je suis parti de la phrase

Citation :


la fonction replicate() répète m fois la fonction spécifiée (ici Appel() ) et fournit les résultats dans un vecteur de dimension m  


 
Pour le coup des liste plates je suis d'accord pour utiliser la récursivité, mais je ne vois pas de liste plate ici. En effet :
- quand on appelle récursivement, on ne joue pas sur une liste
- ni le "retour" de la récursion ne "construit" de liste (car z semble être un entier)
 
Donc pour moi m n'est pas un conteneur


 
Sauf que là, j'ai l'impression qu'il y a un truc qui n'est pas clair : Appel() semble n'être appelé qu'une seule fois et c'est son résultat qui semble être répliqué.
Cela dit, ton point est parfaitement valide, j'en conviens  [:dawa]  
 
Cela dit, la syntaxe utilisée par rockr ne semble pas coller à la définition du langage R que j'ai trouvée, et replicate ne fait pas partie non plus de la lib standard ... Donc je commence à me dire qu'il y a trop de trous dans les explications pour pouvoir être d'un grand secours.


---------------
last.fm
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed