IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

MATLAB Discussion :

Trouver les points d'inflexion d'une courbe


Sujet :

MATLAB

  1. #1
    Candidat au Club
    Homme Profil pro
    Ingénieur validation
    Inscrit en
    Mai 2016
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur validation

    Informations forums :
    Inscription : Mai 2016
    Messages : 6
    Points : 2
    Points
    2
    Par défaut Trouver les points d'inflexion d'une courbe
    Bonjour à tous,

    Avant tout je vous remercie de toute aide que vous porterez sur ce post.

    Voila l'histoire: j'ai une courbe de mesure ( cf Courbe).
    Nom : Courbe.png
Affichages : 4926
Taille : 48,7 Ko
    Cette courbe possède différents points d'inflexion. Je précise que je n'ai pas la fonction de cette courbe et que aucune courbe de tendance ne peut s'y appliquer.

    Je souhaiterai donc mettre en place un programme me permettant de trouver ces points d'inflexion.

    Pour cela je suis parti pour calculer tous les coefficients directeurs entre chaque points.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Point_A=load('V10_2_A.txt');
     
    Freq=Point_A(:,1);
    Ampl=Point_A(:,2);
     
    i=1;
     
    for i=1:length(Ampl)-1
     
        Coef(i)=(Ampl(i+1)-Ampl(i))/(Freq(i+1)-Freq(i));
     
     
        i+1;
    end
    Une fois que j'ai récupéré les coefficients, je souhaite donc comparer les signes de chacun pour connaitre la tendance. Le but est que si la tendance est la même pendant (par exemple) 20 itérations, et que l'itération d'après la tendance change alors le point de la 20ème itération est un point d'inflexion.

    Exemple de code (pas fonctionnel)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
     
    t=0;
    u=linspace(1,3200,3200);
    for j=1:length(Coef)
     
       q=20; % compteur limite de définition de points d'inflexion
     
       if sign(Coef(j))==sign(Coef(j+1))
           t=t+1; % compteur 
       else t=0;
     
           if t-1>q || t=0
               Point_inflexion(u)=Coef(j-1);
               X(i)=Freq(j-1);
               Y(i)=Ampl(j-1);
               u=u+1;
           else 
           end
       end
     
    end
    Mon problème est le suivant: En se basant sur la méthode appliqué pour trouver les points d'inflexion, il se peut que le calcul me trouve une variation de tendance au bout de 20 itérations mais qui ne correspond pas forcément à un point d'inflexion, reprendre la boucle avec le compteur à 0 et ne pas trouver le points d'inflexion se trouvant a 15 itérations après (par exemple).

    En clair l'idée de mon deuxième code n'est pas la bonne ou alors pas complète.

    Je me tourne donc vers vous, comment feriez vous pour trouver les points d'inflexion d'une courbe ( sachant que ce ne sont pas forcément les min/max de la courbe)? Avez vous un exemple de programme?

    Je vous remercie encore, car toute aide est la bienvenue.

  2. #2
    Modérateur
    Avatar de le fab
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    1 881
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 881
    Points : 3 429
    Points
    3 429
    Par défaut
    salut

    l'idée est regarder les changement de signe de la dérivée seconde
    tu peux obtenir une dérivée via la fonction diff (diff(diff(mesPoint)) pour une dérivée seconde)

    après pour éviter de trouver des points d'inflexion là ou il n'y en a pas, le mieux est d'appliquer un filtre sur ton signal
    un filtre moyenne sur fenêtre glissante par exemple ferait très bien l'affaire

    pour trouver les changements de signes dans un vecteur, la fonction find peut être utile :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    vIdxChgtSigne = find(sign(monVecteur(1:end-1) ~= sign(monVecteur(2:end)) +1 ;
    Fabien

  3. #3
    Candidat au Club
    Homme Profil pro
    Ingénieur validation
    Inscrit en
    Mai 2016
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur validation

    Informations forums :
    Inscription : Mai 2016
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Merci pour ta réponse.

    Je ne comprends pas en quoi le filtre pourrait m' aider à trouver les bons points d'inflexion?

    Pour le moment voila ce que j'ai faits:

    Chargement des données:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Point_A=load('V10_2_B.txt');
     
    Freq=Point_A(:,1);
    Ampl=Point_A(:,2);
    Calcul de moyenne de chaque blocs de 11 points consécutifs:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    j=1;
    for i=1:11:length(Ampl)
     
        MoyAmpl(j)=((Ampl(i)+Ampl(i+1)+Ampl(i+2)+Ampl(i+3)+Ampl(i+4)+Ampl(i+5)+Ampl(i+6)+Ampl(i+7)+Ampl(i+8)+Ampl(i+9)+Ampl(i+10))/11);
        MoyFreq(j)=((Freq(i)+Freq(i+1)+Freq(i+2)+Freq(i+3)+Freq(i+4)+Freq(i+5)+Freq(i+6)+Freq(i+7)+Freq(i+8)+Freq(i+9)+Freq(i+10))/11);
     
        j=j+1;
        i=i+10;
    end
    Calcul des Max de ma courbe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    %% MAX 
    s=1;
    for k=2:1:291-1
     
        X=MoyAmpl(k);
        Y=MoyAmpl(k-1);
        Z=MoyAmpl(k+1);
        W=X-Y;
        N=Z-X;
     
        if X>Y & X>Z 
            %| abs(X-Y)<0.0001 & abs(Z-X)<0.0001
     
     
            Point_inflexionMAX(s)=X;
            FreqInflexionMAX(s)=MoyFreq(k);  
            s=s+1;  
     
     
            end  
     
        end
    Calcul des Min
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    %% MIN    
     
    v=1;
    for k=2:1:291-1
     
        X=MoyAmpl(k);
        Y=MoyAmpl(k-1);
        Z=MoyAmpl(k+1);
     
     
        if X<Y & X<Z
            %| abs(Z-X)<0.0001 & abs(Y-X)<0.0001
     
            Point_inflexionMIN(v)=X;
            FreqInflexionMIN(v)=MoyFreq(k);
    %          if Z*0.95<X<Y*0.05
    %             Point_inflexionMIN(v)=X;
    %         FreqInflexionMIN(v)=MoyFreq(k);
    %         else
     
     
            v=v+1;
             end
        end
    Et maintenant voilà, j'ai donc trouver tous mes MAX et MIN de ma courbe, cependant j'ai des points d'inflexion qui sont présents visuellement mais qui ne présente pas de changement de tendance. Je m'explique:

    Si on reprend la courbe que j'ai mise lors du premier post, nous pouvons voir qu'il y à un point d'inflexion aux alentours de 250 HZ. Mais ce points n'est pas trouvé par aucune des deux méthodes (MIN et MAX), car sa pente ne varie pas! En effet, si on regarde les valeurs, elles sont trés proches à 0.01 ou 0.02 près.

    J'ai donc mis en place une autre condition afin de pouvoir trouver ce (ou ces) point(s) présent(s) sur la courbe.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    %%
    for k=2:1:291-1
     
        X=MoyAmpl(k);
        Y=MoyAmpl(k-1);
        Z=MoyAmpl(k+1);
     
     if 0.01<(abs(X)-abs(Z))<0.02 & 0.01<abs(X-Y)<0.02
            %| abs(X-Y)<0.0001 & abs(Z-X)<0.0001
     
     
            Point_inflexionVar(s)=X;
            FreqInflexionVar(s)=MoyFreq(k);  
            s=s+1;  
     
     
            end 
    end
    Mais cette condition ne trouve pas ce genre de points.
    Est ce que tu as une idée?

    Ps: Je rappel que l'objectif est de pouvoir trouver tous mes points d'inflexion et j'ai donc réalisé 3 méthodes pour tous les trouvé. Et la dérivé seconde passe aussi à de ces points où le changement de tendance n'est pas significatif.

    Merci encore!

  4. #4
    Modérateur
    Avatar de le fab
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    1 881
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 881
    Points : 3 429
    Points
    3 429
    Par défaut
    salut

    le filtrage est là pour éviter que l'algo se fasse piéger par un éventuel bruit sur ton signal et pour gommer les "plats" qui empecheront la détection de chgt de signe (sign = 0)
    si ton signal est parfait, pas besoin

    essayes un truc de ce style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    % dérivee
    dampl = diff(ampl);
    % derivee seconde
    ddampl = diff(dampl);
     
    % index des pts d'inflexion
    % ajout décalages à cause des 2 dérivées et de la recherche de changement de signe
    idxInfexion = find(sign(ddampl(1:end-1)) ~= - sign(ddampl(2:end))) + 2 + 1;  
     
    % tracé sur le graphique des points d'inflexions trouvés
    hold on
    plot(freq(idxInfexion), ampl(idxInflexion), 'ro')

Discussions similaires

  1. Comment trouver les points des inflections pour une courbe
    Par mihaispr dans le forum Mathématiques
    Réponses: 3
    Dernier message: 30/09/2009, 14h25
  2. Trouver les points d'inflexion d'une courbe lissajou
    Par Ballim dans le forum Mathématiques
    Réponses: 7
    Dernier message: 23/09/2009, 12h31
  3. Trouver les fichiers x jours après une date
    Par rd07110 dans le forum Scripts/Batch
    Réponses: 3
    Dernier message: 19/02/2008, 12h43
  4. trouver les points x et y de la cellule "a1"
    Par patbou dans le forum Macros et VBA Excel
    Réponses: 17
    Dernier message: 12/02/2008, 20h27
  5. [RegEx] Trouver les mots en majuscule dans une chaine
    Par Boeing dans le forum Langage
    Réponses: 2
    Dernier message: 15/10/2007, 23h44

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo