Partage
  • Partager sur Facebook
  • Partager sur Twitter

Calcul des coefficients complexes de Fourier

    1 août 2018 à 15:43:01

    Bonjour, je tente de programmer un algorithme qui à partir d'un ensemble de points dans le plan, me retourne les coefficients complexe de la série de Fourier approximant la courbe passant par ces points. Mon problème est donc un problème à la fois mathématique et programmation (python).

    (désolé je ne parviens pas après plusieurs tentatives de transformer certaine formule mathématique en latex en code mathématique affichable, j'ai bien lu le topic consacré)

    En plus claire j'ai un ensemble de points P1,P2,P3,...,PN. En reliant P1 à P2, P2 à P3, .... et enfin PN à P1, on obtient une courbe qui est fermée.

    Exemple par une image :

    Cette courbe peut être écrite comme une fonction complexe paramétrée par la variable t et est périodique puisque la courbe forme une courbe fermée (contour). Elle se note donc Z(t). Or par Fourier, on peut approximer cette courbe par une somme d'exponentielle complexe avec N fixé : \(Z(t) = a_{0} + a_{1} e^{jt} + a_{2} e^{2jt} + ... + a_{N} e^{N j t} + a_{-1} e^{-j t} + a_{-2} e^{-2jt} + ... + a_{-N} e^{-N j t}\)

    Selon Fourier, les paramètres : \(a_0,a_1,a_2,...,a_N,a_{-1},a_{-2},...,a_{-N}\) peuvent être obtenu par \( a_i = \frac{1}{2 \pi} \int_{0}^{2 \pi} Z(t) e^{-jit} dt  \) avec j le complexe imaginaire pure : \(j^2=-1\).

    J'ai donc écrit un petit programme python pour approximer ces intégrales et donc déterminer les paramètres \(a_i\).

    En écrivant \(Z(t) = X(t) + j Y(t)\) et \(e^{-jit} = \cos(it)-j \sin(it)\), j'ai ré-écrit l'intégrale $$a_i = \frac{1}{2 \pi} \displaystyle \int_{0}^{2 \pi} Z(t) e^{-jit} \, \mathrm{d}t = \frac{1}{2 \pi} \left( \displaystyle \int_{0}^{2 \pi}  X(t) \cos(it) + Y(t) \sin(it)  \, \mathrm{d}t  + j \displaystyle \int_{0}^{2 \pi}  Y(t) \cos(it) - X(t) \sin(it)  \, \mathrm{d}t  \right)$$

    J'approxime donc \(a_i\) par dans le code  \(I1 + j I2\) avec la méthode des rectangles.

    def coeffFourier(Points,N):
        Params = []
        
        for i in range(0,N):
            Ai = coeff(i,Points)
            
            Params.append(A_i)
            
            if i !=0:
                i = -1*i
                Ai = coeff(i,Points)
                
                Params.append(A_i)
            
        return Params
        
    def coeff(i,Points):
    '''Calcul le nombre complexe a_i'''
        T = 2*np.pi # periode
        nbIteration = len(Points)
        delta_t = T/nbIteration
        I1 = 0
        I2 = 0
        for n in range(nbIteration):
            I1 = I1 + (Points[n][0]*np.cos(i*n*delta_t) + Points[n][1]*np.sin(i*n*delta_t))*delta_t
            I2 = I2 + (Points[n][1]*np.cos(i*n*delta_t) - Points[n][0]*np.sin(i*n*delta_t))*delta_t
        I1 = I1/T
        I2 = I2/T
        return [I1,I2]

    Alors voilà je me demande donc si le raisonnement effectué ci-dessus est correcte et que mon code approxime bien les coefficients de la série de Fourier.

    J'ai l'impression qu'il y a un problème parce qu'en fait à partir des coefficients \(a_i\) je peux déduire les caractéristiques de plusieurs cercles tel que le centre du second cercle tourne sur la circonférence du premier cercle et dont le troisième cercle tourne sur la circonférence du deuxième cercle et ainsi de suite. Le dernier point tournant sur le dernier cercle dessine alors la courbe initiale. En fait j'essaye de programmer l'éléphant de Fermi & Neumann présenté dans la très intéressante vidéo

    "Deux (deux ?) minutes pour l'éléphant de Fermi & Neumann"       de la chaine youtube El Jj.

    Quand j'applique mon algorithme pour trouver les \(a_i\) et qu'ensuite je déduis les caractéristiques des cercles pour dessiner la courbe mais le résultat ne ressemble à rien.

    Merci de votre aide si vous déceler une erreur dans ce raisonnement.

    Bonne journée !

    -
    Edité par SIM4bel 2 août 2018 à 14:03:48

    • Partager sur Facebook
    • Partager sur Twitter
      1 août 2018 à 16:45:05

      Par curiosité, peux-tu poster le dessin obtenu (et le dessin original, mais je suppose que l'original est celui que tu as déjà posté).

      Je ne suis pas familier de Fourier. Mais mon intuition, c'est qu'il faut beaucoup plus d'itérations

      • Partager sur Facebook
      • Partager sur Twitter
        1 août 2018 à 17:13:42

        En fait le nombre d'itération dépend du nombre de points échantillonnés sur le contour : je peux avec mon programme générer beaucoup plus de points.

        Par exemple sur l'image précédente il y avait 100 points et sur l'image suivante il y a 1000 points :

        J'applique ensuite l’algorithme (code python) ci-dessus et déduis  les \(a_i\). Des  \(a_i\) je déduis le rayon et l'angle initiale des cercles

        rayon du cercle i   =  module( \(a_i\) )

        angle initiale (t = 0)    =  angle( \(a_i\) )

        la vitesse du cercle i  =  i

        de là je crée alors la configuration initiale des cercles :

        (image avec 1000 points sur le contour et N=5 dans la série de Fourier)

        J'anime alors et trace la trajectoire formée par le point vert (dernier point) et la courbe dessinée devrait redessiner le tigre mais c'est pas du tout le cas.

        Je suis conscient que mettre N=5 et bien trop peu, il faut considérer plus de termes dans la série de Fourier mais j'ai mis 5 pour voir graphiquement mais en pratique j'ai déjà essayer avec N = 300 et le résultat n'est pas tellement mieux alors que N=300 est théoriquement largement trop.

        La courbe obtenue est la noir dans l'image ci-dessous :

        -
        Edité par SIM4bel 1 août 2018 à 17:29:46

        • Partager sur Facebook
        • Partager sur Twitter
          3 août 2018 à 14:01:52

          Edit: Si tu veux exprimer des coefficients de Fourier tu peux simplement utiliser la fonction scipy.signal.fft.

          -
          Edité par Nozio 3 août 2018 à 14:03:22

          • Partager sur Facebook
          • Partager sur Twitter

          Avez-vous entendu parler de Julia ? Laissez-vous tenter ...

            6 août 2018 à 22:21:35

            Une simple remarque de programmation: je me demande comment ton code tel que posté ci-dessus  peut tourner : à la ligne 5, tu appelles le coefficient Ai et dans la construction de Params ligne 7, tu appelles ce coefficient A_i , donc normalement Python déclare "variable non définie" .

            J'ai testé et c'est ce qui se passe, le programme plante. Si je modifie pour avoir un seul nom ( au choix Ai ou A_i évidemment),je sors bien alors les coefficients ( j'ai testé pour retrouver des  formes simples   dont on connait l'équation paramétrique explicite, et cela semble fonctionner) (*) .Donc le calcul des coefficients semble  correct.

            Si, pour je ne sais quelle raison :o, ton code fonctionne néanmoins tel quel, je me demande  quelles valeurs Python peut bien mettre  dans Params !    Ton problème pourrait éventuellement venir de là . 

            (   autre possibilité :une simple erreur de lecture dans la manipulation de la liste des coefficients de Fourier; à ma première tentative c'est ce qui m'est arrivé et mon résultat, c'était n'importe quoi).

            edit

            (*) exemple: reconstruction par Fourier d'une astroïde :p avec un échantillonnage de 10 points :

            -
            Edité par Sennacherib 7 août 2018 à 10:15:53

            • Partager sur Facebook
            • Partager sur Twitter
            tout ce qui est simple est faux, tout ce qui est compliqué est inutilisable
              16 août 2018 à 3:12:41

              Salut !

              Marrant comme sujet. :) J'ai quelques remarques à apporter.

              Première remarque : au vu de ta fonction coeffFourier, il faut que tu fasses attention à deux éléments :

              • d'abord, N doit toujours être inférieur à len(Points)//2
              • ensuite, tu choisis une convention étonnante pour l'ordre de sauvegarde des coefficients pour les fréquences positives et négatives...

              Seconde remarque : tu as bien fait de réaliser le calcul des coefficients pour les fréquences négatives. Comme ton signal est complexe, ton spectre de Fourier ne sera pas pair.

              Troisième remarque : il semblerait (je dis bien «semblerait») que ton code pour le calcul des coefficients de Fourier doive marcher (erreur du A_i mise-à-part). Ceci-dit, il existe moult conventions différentes pour la transformée de Fourier, et ton résultat va grandement dépendre de la manière dont tu exploites les coefficients obtenus dans la suite du code. Peux-tu nous montrer la partie qui calcule les caractéristiques des cercles à partir des coefficients de Fourier ? Je pense que s'emmêler les pinceaux niveau convention choisie est le plus facile (par exemple oublier que le tableau renvoyé par coeffFourier(Points, N) est de longueur 2N+1, alternant fréquences positives et négatives, etc).

              PR

              • Partager sur Facebook
              • Partager sur Twitter
                16 août 2018 à 12:37:02

                PR, pour ce qui est de ta troisième remarque, les conventions sont avant tout des facteurs de normalisation. Du coup, si le calcul est juste, on devrait retrouver quand même la courbe initiale.

                • Partager sur Facebook
                • Partager sur Twitter

                Avez-vous entendu parler de Julia ? Laissez-vous tenter ...

                  16 août 2018 à 22:07:38

                  Si le calcul est juste, alors la courbe sera juste, certes.

                  Ce que je voulais dire, c'est que l'erreur a de grandes chances de se trouver dans l'interprétation des coefficients de Fourier. ;)

                  PR

                  • Partager sur Facebook
                  • Partager sur Twitter
                    16 août 2018 à 22:44:53

                    Salut, je n'ai absolument pas le niveau, mais les épicycloïdes ne sont pas intéressantes ici ? 

                    Ce me fait penser à l'éléphant de Fermi et Neumann que El Jj traite dans cette vidéo: 

                    https://www.youtube.com/watch?v=uazPP0ny3XQ

                    En espérant avoir aidé :/ 

                    -
                    Edité par Kyrtu 16 août 2018 à 22:45:10

                    • Partager sur Facebook
                    • Partager sur Twitter

                    Calcul des coefficients complexes de Fourier

                    × 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