Partage
  • Partager sur Facebook
  • Partager sur Twitter

comment implémenter cet algorithme récursif

    23 août 2009 à 3:12:36

    Bonjour à tous,

    j'ai trouvé dans le net cet algorithme récursif, ci-dessous, je suis debutant en programmation et je veut l'implémenter en java. Ce programme s'appelle algorithme de Levinson-Durbin.

    voici le pseudo-code:

    Valeurs initiales :
    E0= R(0) = (1/T) ∑t |x*x| et a0(0) = 1

    Pour N = 1,.., M-1, répéter :

    1. kN = - [R(N)*a(N-1)(0) + …. + R(1)*a(N-1)(N-1)] / E(N-1)

    2. Pour n Є {2, …, N-1} :
    aN(0) = 1
    aN(n) = a(N-1)(n) + kN a(N-1)(N-n)
    aN(N) = kN

    3. EN = E(N-1)(1 - (kN*kN))

    Où :

    a : les coefficients LPC
    N : indice qui varie
    R : les coefficients de la matrice d’auto-corrélation qui de type Toeplitz
    M : la dimension de la matrice
    T : nombre d’échantillons du signal de parole
    t : (je crois) les instants de l'échantillonnage
    K : les coefficients de réflexion
    E : l'erreur quadratique
    x : c'est le résultat de la lecture d'un fichier audio, ces données sont utilisées pour construire la matrice d'autocorrélation

    aussi j'ai trouvé un bout de code en java qui l'implémente mais il besoin de beaucoup de choses et j'ai pas arriver à le developper.


    public class LevinsonDurbin 
    {
    	int order ;                         // l'ordre de prédiction linéaire souvent = 16    
    	
    	public LevinsonDurbin(int orderp)
    	{
    		 order = orderp;
    	}
    	
    	// déclaration des variables
    	double a[][]= new double[order][order];  // les coefficients LPC 
    	double R[]= new double[order];      // les coefficients de la matrice d'autocorrélation
    	double k[]= new double[order];      // les coefficients de reflextion
    	double E[]= new double[order];      // l'erreur quadratique
    		
    	
    	 public void reflexionCoefficient(int M)
    	 {	
    		 for(int N=1;N<=M-1;N++) 
    		 {		
    			 for(int i=0;i<=N-1;i++)
    			 {
    				 k[N]+= -(R[N-i]*a[N-1][i])/E[N-1];
    			 } 	     
    		 }	
    	}
    	
    	public void LPC(int M)
    	{
    		// je croie que n doit commencer par 1, sinon on aura un problème pour 
    		// calculer a[N][n] 
    		for(int N=1;N<=M-1;N++) 
    		{		
    				for(int n=2;n<=N-1;n++)  
    				{
    					a[0][0]= 1.0;
    					
    					a[N][0]=1;
    					a[N][n]=a[N-1][n]+k[N]*a[N-1][N-n]; 
    					a[N][N]=k[N];
    	        
    					System.out.print(a[N][n]+" ");
    				}			
    		}
    	}
    	
    	public void autocorrelation()
    	{
    		
    	}
    	
    	public void error(int M)
    	{
    		for(int N=1;N<=M-1;N++) 
    		{
    		 E[N]= E[N-1]*(1-(k[N]*k[N]));  
    		}
    	}
    	
    	float som = 0;
    	
    	public void sum(int T, float x[] )     // x sont les données audio
    	{ 
    		// je veux appeler le tableau de la méthode run() qui est dans la classe MonThread 		
    		for(int i=0; i< MonThread.run().bytes.length);i++)
    			som +=(1/T)*(x[i]* x[i]);           //T c'est le nombre des échantillons			
    	}	
    }
    


    j'ai la classe MonThread qui lit les fichiers audio et donne les coefficients x.

    pour se renseigner sur cet algorithme, vous pouvez voir les liens suivants:


    http://ltswww.epfl.ch/~coursitsb/fil...lineaire_1.pdf

    http://externe.emt.inrs.ca/users/ben.../lecture04.pdf

    si quelqu'un veut m'aider je serais reconnaissant pour lui et merci à vous tous.
    • Partager sur Facebook
    • Partager sur Twitter
      23 août 2009 à 8:57:59

      La moindre des choses serait de poster en <math>\(Latex\)</math> et de nous expliquer toi même un peu l'algo, et de nous dire les points précis où tu bloques, plutôt que de nous demander tout le travail.
      • Partager sur Facebook
      • Partager sur Twitter
      Anonyme
        23 août 2009 à 9:47:26

        Citation : Soukayman

        je suis debutant en programmation



        c'est pas une excuse

        "j'ai pas mon permis mais je veux piloter une F1" ca te semble credible toi?
        • Partager sur Facebook
        • Partager sur Twitter
          23 août 2009 à 13:19:54

          Attends... tu as repris tout le code d'ici ?> http://www.developpez.net/forums/d7923 [...] -durbin-java/

          Donc tu as rien compris au code présenté, donc tu sais pas où ça cloche et en plus vu le code tu doit pas savoir ce qu'est la récursivité. Je te conseille de commencer plutôt par programmer une factorielle et après tu pourras te lancer très gentiment là-dedans.
          • Partager sur Facebook
          • Partager sur Twitter
            23 août 2009 à 13:25:57

            Bonjour à tous,

            Merci d'avoir répondu, je m'excuse, j'ai fait beacoup de recherche et je veut juste vos aides.

            Cet algorithme sert à extraire les caractéristiques de la parole et il est inscrit dans le domaine de la reconnaissace du locuteur, je veux bien l'implémenter.

            On donne à ce programme les données audio + l'ordre du modèle de prédiction linéaire et nous renvoie les coefficients LPC qui caractérisent la personne.

            je me suis bloqué pour le rendre récursif car cette implémentation est directe, ensuite la fonction autocorrélation doit prendre des données d'une autre classe qui lit un fichier wav et cette fonction est une matrice de type Toeplitz. à votre avis comment faire ça ?

            aussi, à mon avis, le constructeur dois prendre l'ordre du modèle et les données audio mais tous va changer.

            la classe lisant un fichier wav marche bien mais avec certains et pas avec d'autre (donc je doit résoudre le problème d'une exception qui se lève mais après)est:

            import java.io.File;
             
            import javax.sound.sampled.AudioFormat;
            import javax.sound.sampled.AudioInputStream;
            import javax.sound.sampled.AudioSystem;
            import javax.sound.sampled.DataLine;
            import javax.sound.sampled.LineUnavailableException;
            import javax.sound.sampled.SourceDataLine;
              
            public class WavPlayer 
             {
                 public static AudioInputStream audioStream = null;
                 public static SourceDataLine line = null;
                 private AudioFormat audioFormat = null;
                 
                 public WavPlayer(File f) throws Exception
                 {
                	 //	recuperation d'un stream de type audio sur le fichier
                	 /** En théorie, pour lire un fichier son, il faut lire le contenu du fichier et 
                	  *  l'écrire sur la ligne qu'on a créer avec les paramètres qui vont bien.
                	  *  Pour la capture, on lit depuis la ligne qui va bien et on écrit dans un flux 
                	  *  sortant */
                	 
                     audioStream = AudioSystem.getAudioInputStream(f);
                    
                     // recuperation du format de son
                     audioFormat = audioStream.getFormat();
                     System.out.println(audioFormat); 
            
                     // recuperation du son que l'on va stoquer dans un objet de type SourceDataLine
                     DataLine.Info info = new DataLine.Info(SourceDataLine.class,audioFormat);
             
                     try 
                     {
                    	 //	recuperation d'une instance de type SourceDataLine
                    	 line = (SourceDataLine) AudioSystem.getLine(info);
                     } 
                     catch (LineUnavailableException e) 
                     {
            		     e.printStackTrace();
                     }		
                 }
                 
                 /**
                  * Ouverture du flux audio
                  * @return On retourne <code>false</code> si il y a eu une erreure
                  */
                 public boolean open()
                 {    	 
                         try 
                         {
                        	 line.open(audioFormat);
                         } 
                         catch (Exception e) 
                         {
                             e.printStackTrace();              //pour le debugage
                             return false;
                         }
                     return true;
                 }
                 
                 /**
                  * Fermeture du flux audio
                  */
                 public void close()
                 {
                     line.close();
                 }
                 
                 /**
                  * On joue le son
                  */
                 public void play()
                 {
             
                	 MonThread t = new MonThread();
                	 t.start();	
                	 System.out.println("test\n");
                 }
                 
                 /**
                  * On arrete le son
                  */
                 public void stop()
                 {
                	 line.stop();
                 }
                      
                 public static void main(String [] args)
                 {       
                	 try {
                         WavPlayer wp = new WavPlayer(new File("C:\\Documents and Settings\\admistrateur\\Bureau\\lazer.wav"));
            
                         wp.open();
                         wp.play();
                         Thread.sleep(100);   // fait patienter 0.1 seconde
                        // int i = 0;
                        /** while(i <= 10){
                        	 Thread.sleep(1000);   // fait patienter une seconde
                        	 System.out.println(i);
                        	 i++;
                         }*/
                         wp.stop();
                         wp.close();
                         System.out.println("\ndebug0");
                	 } 
                	 catch (Exception e)
                	 {
                         e.printStackTrace();
                     }         
                 }
             }
            


            et la classe MonTread est:

            import java.io.IOException;
              
            public class MonThread extends Thread
            {	
            	public MonThread()
            	{
            	}
             
            	public void run()
            	{
            		WavPlayer.line.start();
            		 try {
            				byte bytes[] = new byte[1024];
            	 			int bytesRead=0;
            	 			// cette boucle permet de lire tout le fichier avant de s'arêter 
            	 				
            	 		 		
            	 			while (((bytesRead = WavPlayer.audioStream.read(bytes, 0, bytes.length)) != -1)) 
            	 			{
            	 				WavPlayer.line.write(bytes, 0, bytesRead);
            	 					
            	 			}
            	 			for(int i=0;i<29;i++)
            	 			{
            	 				System.out.print( bytes[i]+" ");	
            	 			}	 				
            	 	 } 
            		 catch (IOException io)
            	 	 {
            	 		io.printStackTrace();
            	 		return;
            	 	 }	
            	}
            }
            


            merci d'avance
            • Partager sur Facebook
            • Partager sur Twitter
              23 août 2009 à 13:36:43

              Une méthode récursive est une méthode qui s'appelle sur elle même.

              Donc tu fais un truc du genre :
              public void methode () {
                    //Le code.
                    methode ();
              }
              


              Le tout est de savoir quand il faut s'arrêter pour ne pas appeler la méthode indéfiniment sur elle même.
              (Sinon StackOverflowException.)

              Maintenant pour le reste je ne saurai pas t'aider vu que je ne comprends rien à ton truc.

              • Partager sur Facebook
              • Partager sur Twitter
                23 août 2009 à 15:50:01

                Merci,

                oui je suis d'accord, et elle va s'arrêter jusqu'au dernier paramètre qu'on va lui donner.
                • Partager sur Facebook
                • Partager sur Twitter
                  23 août 2009 à 16:14:29

                  Bah alors qu'est ce qui t'empêche d'implémenter ça ?

                  • Partager sur Facebook
                  • Partager sur Twitter
                    24 août 2009 à 0:49:38

                    Bonjour,

                    ce qui m'empèche de l'implémenter d'abord je suis débutant en programmation et j'ai pas arriver le rendre récursif. j'ai essayé et j'ai ajouté grande chose. peux-tu m'aider ?

                    merci d'avance


                    • Partager sur Facebook
                    • Partager sur Twitter
                      24 août 2009 à 7:47:49

                      Voilà un pseudo-code de l'algorithme récursif :

                      algo(N) :
                        si N = 0 alors
                          renvoyer les valeurs initiales
                        sinon
                          obtenir k(N-1), E(N-1) et a(N-1) en appelant algo(N-1)
                          définir k(N) = [R(N)*a(N-1)(0) + …. + R(1)*a(N-1)(N-1)] / E(N-1)
                          définir E(N) = E(N-1)(1 - k(N) * k(N))
                          définir a(N) = un nouveau tableau de taille N
                          a(N)[0] <- 1
                          a(N)[N] <- k(N)
                          pour i de 2 à N - 1 :
                            a(N)[i] <- a(N-1)[i] + k(N) * a(N-1)[N-n]
                          enfin renvoyer k(N), E(N) et a(N)


                      Qu'est-ce qu'il te manque pour produire le code Java à partir de ça ?

                      NB : dans ton code, tu ne vas pas nommer k(N-1) la valeur reçue de algo(N-1), ni k(N) la valeur courante. Il faut leur donner des noms de variable sans indices, comme prev_k (k précédent) pour k(N-1) et k pour K(N) par exemple.
                      • Partager sur Facebook
                      • Partager sur Twitter
                        24 août 2009 à 12:19:34

                        Bonjour,

                        J'ai choisis cet algo pour bien se lancer dans la programmation, mais il parait qu'il est difficile pour moi :( . Mais si vous m'aidez je vais dépasser cette difficulté. :)

                        Donc ma fonction récursif dans ce cas est: algo(N) ? (et le constructeur ? )
                        et j'ai trois valeurs initials, je peux faire:

                        return a[0][0]= 1.0 & R(0)=? & E(0)=?;
                        


                        ensuite, que voulez-vous dire de "obtenir" k(N-1), E(N-1) et a(N-1) en appelant algo(N-1) ? donc, il faut d'abord déclarer les variables k, E et a comme des tableau, ensuite écrire:

                        k(N) = [R(N)*a(N-1)(0) + …. + R(1)*a(N-1)(N-1)] / E(N-1)

                        comme :
                        k[N]+= -(R[N-i]*a[N-1][i])/E[N-1];
                        


                        ensuite vous avez dit:

                        Citation

                        définir a(N) = un nouveau tableau de taille N



                        est-ce que je doit déclarer a(N) deux fois ?

                        encore une chose: vous avez fait:

                        pour i de 2 à N - 1 :
                              a(N)[i] <- a(N-1)[i] + k(N) * a(N-1)[N-n]

                        pourquoi le n ?

                        merci bien pour vos aides.
                        • Partager sur Facebook
                        • Partager sur Twitter
                          24 août 2009 à 21:46:00

                          Alors : moi je ne connais pas les détails de ton langage de programmation. Je ne te serai pas d'un grand secours pour les questions sur "et pour le constructeur ?".

                          Autre remarque annexe : le problème de ton problème c'est pas qu'il est spécialement dur, mais plutôt qu'il est dans un domaine scientifique spécialisé : toi tu connais le domaine, mais tu ne sais pas programmer, les autres gens savent programmer mais ne connaissent pas le domaine, du coup c'est dur de communiquer.

                          Dernière remarque : ici tu peux tutoyer les gens. Ça ne manque pas de respect, c'est la norme.

                          Pour tes questions :

                          Citation

                          Donc ma fonction récursif dans ce cas est: algo(N) ? (et le constructeur ? )


                          J'ai appelé "algo" la fonction qui renvoie les coefficients. En Java ça correspond (je pense) à une méthode statique de classe, donc tu n'as pas besoin de constructeur à priori (comme pour la fonction "main").

                          return a[0][0]= 1.0 & R(0)=? & E(0)=?;

                          Non, ce code n'est pas bon. Il faut que tu utilises une méthode spécifique à ton langage pour renvoyer trois valeurs. Je ne connais pas Java mais je vois deux possibilités différentes :
                          1. passer à ta fonction des références qu'elle modifie pour y mettre les valeurs de retour
                          2. définir une classe qui contient ces trois valeurs, et renvoyer une instance de cette classe

                          Pour les détails, réfère-toi à ton cours de Java où a l'aide d'autres programmeurs.

                          Pour la suite : mon pseudo-code est juste un pseudo-code, il faut que tu le traduises en vrai code Java (encore une fois je te laisse faire). En particulier, pour calculer k(N), il faut que tu écrives une boucle qui calcule la somme avec les trois petits points.

                          Citation

                          est-ce que je doit déclarer a(N) deux fois ?


                          Non, tu commences par l'initialiser (la ligne "définir" correspond sans doute en Java à a = new float[n], où "n" est la variable Java correspondant au N de mon mini-code).

                          Citation

                          pourquoi le n ?


                          Erreur d'inattention de ma part, désolé :
                          pour i de 2 à N - 1 :
                                a(N)[i] <- a(N-1)[i] + k(N) * a(N-1)[N-i]

                          • Partager sur Facebook
                          • Partager sur Twitter
                            25 août 2009 à 1:05:41

                            Pour ce qui est de la récursivité en Java c'est très simple et ici il y a pleins d'exemple => http://pauillac.inria.fr/~levy/x/tc/po [...] /main006.html

                            Et là un exemple de calcul de somme des nombres de n à 0 en Java =>
                            public static int somme(int n) {
                                    if (n == 0) { // Condition d'arrêt 
                                        return 0;
                                    } else {
                                        return (n + somme(n-1));
                                    }
                                }
                            

                            Si tu mets n = 3 dans la fonction somme voici ce que cela fera :
                            - rend 3 + somme de 2
                            - rend 3 + 2 + somme de 1
                            - rend 3 + 2 + 1 + somme de 0
                            - rend 3 + 2 + 1 + 0
                            Au final tu auras donc 6!!!
                            • Partager sur Facebook
                            • Partager sur Twitter
                              25 août 2009 à 11:35:28

                              Bonjour,

                              Je vous remercie, bluestorm et janulrich00001 de m'avoir répondu, sans doute vos conseils et suggestions vont mon servir dans mon travail.

                              pour ton exemple de la somme, il est identique à la factorielle, elle sont faciles, j'ai compris leurs principes de fonctionnement, mais malgré ça je trouve une difficulté devant cet algo.

                              le site que que tu m'as données est très interessant, encore une fois merci beaucoup.
                              • Partager sur Facebook
                              • Partager sur Twitter

                              comment implémenter cet algorithme récursif

                              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                              • Editeur
                              • Markdown