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

Delphi Discussion :

Problème d'équation logarithmique


Sujet :

Delphi

  1. #1
    Membre habitué
    Homme Profil pro
    Owner
    Inscrit en
    Décembre 2004
    Messages
    466
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Owner
    Secteur : Santé

    Informations forums :
    Inscription : Décembre 2004
    Messages : 466
    Points : 137
    Points
    137
    Par défaut Problème d'équation logarithmique
    Bonjour,
    Je cherche à calculer une équation logarithmique à partir de points.
    Excel me fait ça très bien, mais je cherche à intégrer cela dans Delphi.
    Les valeurs de x sont:
    2,5
    5
    10
    15
    25
    Les valeurs de Y sont:
    5,032356374
    5,644094649
    6,339403643
    7,02808909
    7,553404206
    La résolution proposée par excel est:
    y=1.1151*Ln(x)+3.9207

    d'avance pour vos idées...
    Phil

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Déjà comment tu fais cela en EXCEL ? un opérateur ? une macro ?

    Est-ce que la formule à trouver est toujours de la forme y = a * ln(x) + b ?
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Bonjour,

    ShaiLeTroll : Est-ce que la formule à trouver est toujours de la forme y = a * ln(x) + b ?
    Si c'est le cas, le problème de PhilLU se ramènerait à calculer a et b via un système de 5 équations à 2 inconnues vu qu'il y a 5 paires de données X,Y
    Et 5 équations pour seulement 2 inconnues ça fait toujours 3 équations de trop qui donnent des résultats qui s'écartent de celui obtenu par l'un des systèmes de 2 équations à 2 inconnues.
    Donc il suffirait de savoir comment procède Excel mais en cherchant "y = a * ln(x) + b" sur Google on trouve par çi et par là des bouts de réponse.

    A.

    EDIT : On trouve ici : http://www.apprendre-en-ligne.net/MA...ATI/STATI2.PDF
    en Page 20 - CHAPITRE 2 "Ajustement par une fonction logarithmique de la forme y = a ln(x) + b" la façon de calculer a et b via un calcul en 3 étapes dont la seconde passe par un calcul des moindres carrés
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  4. #4
    Membre habitué
    Homme Profil pro
    Owner
    Inscrit en
    Décembre 2004
    Messages
    466
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Owner
    Secteur : Santé

    Informations forums :
    Inscription : Décembre 2004
    Messages : 466
    Points : 137
    Points
    137
    Par défaut
    Citation Envoyé par Gilbert Geyer Voir le message
    Bonjour,


    Si c'est le cas, le problème de PhilLU se ramènerait à calculer a et b via un système de 5 équations à 2 inconnues vu qu'il y a 5 paires de données X,Y
    Et 5 équations pour seulement 2 inconnues ça fait toujours 3 équations de trop qui donnent des résultats qui s'écartent de celui obtenu par l'un des systèmes de 2 équations à 2 inconnues.
    Donc il suffirait de savoir comment procède Excel mais en cherchant "y = a * ln(x) + b" sur Google on trouve par çi et par là des bouts de réponse.

    A.

    EDIT : On trouve ici : http://www.apprendre-en-ligne.net/MA...ATI/STATI2.PDF
    en Page 20 - CHAPITRE 2 "Ajustement par une fonction logarithmique de la forme y = a ln(x) + b" la façon de calculer a et b via un calcul en 3 étapes dont la seconde passe par un calcul des moindres carrés
    Oui, je pense une régression linéaire d'un nuage de points dont l'axe des X est logarithmique.
    La régression linéaire, je maîtrise, mais pour ce coup là, je sèche sur la méthode à utiliser...

  5. #5
    Membre habitué
    Homme Profil pro
    Owner
    Inscrit en
    Décembre 2004
    Messages
    466
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Owner
    Secteur : Santé

    Informations forums :
    Inscription : Décembre 2004
    Messages : 466
    Points : 137
    Points
    137
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Déjà comment tu fais cela en EXCEL ? un opérateur ? une macro ?

    Est-ce que la formule à trouver est toujours de la forme y = a * ln(x) + b ?
    oui, oui

  6. #6
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 858
    Points : 11 301
    Points
    11 301
    Billets dans le blog
    6
    Par défaut
    Peut-être l'utilisation de la librairie DMath de Jean Debord pourrait-elle te convenir.
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  7. #7
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Bonjour,

    PhilLU : la formule à trouver est toujours de la forme y = a * ln(x) + b
    Oui, je pense une régression linéaire d'un nuage de points dont l'axe des X est logarithmique.
    La régression linéaire, je maîtrise, mais pour ce coup là, je sèche sur la méthode à utiliser...
    Puisque tu maîtrises déjà la régression linaire tu devrais bien maîtriser les étapes 1 à 3 de l'image ci-jointe.
    Il faudrait dire plus clairement sur quoi tu sèches (sur l'étape 1 ? l'étape 2 ? ou la 3 ?) sinon on n'avancera pas.

    A+.

    EDIT : On peut trouver ici : http://fbegin.profweb.ca/ZEA/RegLog.htm
    un bon exemple de résolution numérique d'une régression logarithmique présentée dans sa plus grande simplicité.
    Images attachées Images attachées  
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  8. #8
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Re-salut,

    En fait c'est bête comme chou. Voici un bout de code qui reprend les 7 valeurs numériques de l'exemple d'ici : http://fbegin.profweb.ca/ZEA/RegLog.htm
    sauf qu'au lieu de faire les calculs via les Log-Base-10 je passe directement en Logs-Népériens et j'obtiens les mêmes résultats

    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
    25
    26
    procedure TForm1.bRegLogClick(Sender: TObject);
    var x, y: array[1..7] of Extended; i: integer;
      SigX, SigY, SigLnX, SigYLnX, SigLnX2, b0, b1: Extended;
    begin
      for i := 1 to 7 do x[i] := 2 * i;
      y[1] := 8.9;
      y[2] := 10.9;
      y[3] := 12;
      y[4] := 12.8;
      y[5] := 13.4;
      y[6] := 13.9;
      y[7] := 14.3;
      SigX := 0.0; SigY := 0.0; SigLnX := 0.0; SigYLnX := 0.0; SigLnX2 := 0.0;
      for i := 1 to 7 do begin
        SigX := SigX + x[i];
        SigY := SigY + y[i];
        SigLnX := SigLnX + ln(x[i]);
        SigYLnX := SigYLnX + y[i] * ln(x[i]);
        SigLnX2 := SigLnX2 + sqr(ln(x[i]));
      end;
      b1 := (SigYLnX - SigLnX * SigY / 7) / (SigLnX2 - sqr(SigLnX) / 7);
      b0 := (SigY / 7) - (b1 * SigLnX / 7);
      RichEd.clear;
      RichEd.Lines.Add('y = ' + FloatToStr(b0) + ' + ' + FloatToStr(b1) + ' * Ln(x)');
      // Résultat : y = 7,01664538270682 + 2,77214256629099 * Ln(x)
    end;
    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  9. #9
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Bonjour,

    Voici une version améliorée du code de la régression logarithmique :

    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
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    type TPointsEx = record
        X, Y: Extended;
      end;
     
    type TNuage = array of TPointsEx;
    var Nuage: TNuage;
     
    procedure RegressLog(Nuage: TNuage; var B0, B1: Extended; var StrRes: string);
    var SigX, SigY, SigLnX, SigYLnX, SigLnX2: Extended; i: integer;
    begin
      SigX := 0.0; SigY := 0.0; SigLnX := 0.0; SigYLnX := 0.0; SigLnX2 := 0.0;
      for i := 0 to High(Nuage) do begin
        if Nuage[i].x <= 0.0 then begin
          StrRes := 'Non calculable car présence d''un point X <= 0 : EXIT';
          EXIT;
        end;
        SigX := SigX + Nuage[i].x;
        SigY := SigY + Nuage[i].y;
        SigLnX := SigLnX + ln(Nuage[i].x);
        SigYLnX := SigYLnX + Nuage[i].y * ln(Nuage[i].x);
        SigLnX2 := SigLnX2 + sqr(ln(Nuage[i].x));
      end;
      b1 := (SigYLnX - SigLnX * SigY / length(Nuage)) / (SigLnX2 - sqr(SigLnX) / length(Nuage));
      b0 := (SigY / length(Nuage)) - (b1 * SigLnX / length(Nuage));
      StrRes := 'y = ' + FloatToStr(b0) + ' + ' + FloatToStr(b1) + ' * Ln(x)';
    end;
     
    procedure TForm1.bRegLogClick(Sender: TObject);
    var Nuage: TNuage; B0, B1: Extended; StrRes: string;
    begin
      SetLength(Nuage, 5);
      Nuage[0].X := 2.5;
      Nuage[1].X := 5;
      Nuage[2].X := 10;
      Nuage[3].X := 15;
      Nuage[4].X := 25;
     
      Nuage[0].Y := 5.032356374;
      Nuage[1].Y := 5.644094649;
      Nuage[2].Y := 6.339403643;
      Nuage[3].Y := 7.02808909;
      Nuage[4].Y := 7.553404206;
     
      RichEd.clear;
      RegressLog(Nuage, B0, B1, StrRes);
      RichEd.Lines.Add(StrRes);
    end;
    PhilLU : La résolution proposée par EXCEL est : y = 1.1151 * Ln(x) + 3.9207
    ... et avec le code ci-dessus elle est : y = 3,9207493465945 + 1,11514029375557 * Ln(x)

    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  10. #10
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 345
    Points : 3 123
    Points
    3 123
    Par défaut
    Bonjour,
    comme PhilLu n'a pas clos la discussion et que j'avais un peu de temps pour bidouiller, j'ai repris le code de Gilbert pour afficher le résultat sous forme de courbe.
    A+
    Charly
    CourbeLog.zip

  11. #11
    Membre habitué
    Homme Profil pro
    Owner
    Inscrit en
    Décembre 2004
    Messages
    466
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Owner
    Secteur : Santé

    Informations forums :
    Inscription : Décembre 2004
    Messages : 466
    Points : 137
    Points
    137
    Par défaut
    Citation Envoyé par Gilbert Geyer Voir le message
    Bonjour,

    Voici une version améliorée du code de la régression logarithmique :

    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
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    type TPointsEx = record
        X, Y: Extended;
      end;
     
    type TNuage = array of TPointsEx;
    var Nuage: TNuage;
     
    procedure RegressLog(Nuage: TNuage; var B0, B1: Extended; var StrRes: string);
    var SigX, SigY, SigLnX, SigYLnX, SigLnX2: Extended; i: integer;
    begin
      SigX := 0.0; SigY := 0.0; SigLnX := 0.0; SigYLnX := 0.0; SigLnX2 := 0.0;
      for i := 0 to High(Nuage) do begin
        if Nuage[i].x <= 0.0 then begin
          StrRes := 'Non calculable car présence d''un point X <= 0 : EXIT';
          EXIT;
        end;
        SigX := SigX + Nuage[i].x;
        SigY := SigY + Nuage[i].y;
        SigLnX := SigLnX + ln(Nuage[i].x);
        SigYLnX := SigYLnX + Nuage[i].y * ln(Nuage[i].x);
        SigLnX2 := SigLnX2 + sqr(ln(Nuage[i].x));
      end;
      b1 := (SigYLnX - SigLnX * SigY / length(Nuage)) / (SigLnX2 - sqr(SigLnX) / length(Nuage));
      b0 := (SigY / length(Nuage)) - (b1 * SigLnX / length(Nuage));
      StrRes := 'y = ' + FloatToStr(b0) + ' + ' + FloatToStr(b1) + ' * Ln(x)';
    end;
     
    procedure TForm1.bRegLogClick(Sender: TObject);
    var Nuage: TNuage; B0, B1: Extended; StrRes: string;
    begin
      SetLength(Nuage, 5);
      Nuage[0].X := 2.5;
      Nuage[1].X := 5;
      Nuage[2].X := 10;
      Nuage[3].X := 15;
      Nuage[4].X := 25;
     
      Nuage[0].Y := 5.032356374;
      Nuage[1].Y := 5.644094649;
      Nuage[2].Y := 6.339403643;
      Nuage[3].Y := 7.02808909;
      Nuage[4].Y := 7.553404206;
     
      RichEd.clear;
      RegressLog(Nuage, B0, B1, StrRes);
      RichEd.Lines.Add(StrRes);
    end;

    ... et avec le code ci-dessus elle est : y = 3,9207493465945 + 1,11514029375557 * Ln(x)

    A+.
    Super, merci pour ton aide Gilbert, c'est parfait


  12. #12
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Bonjour,


    Charly910 : comme PhilLu n'a pas clos la discussion et que j'avais un peu de temps pour bidouiller, j'ai repris le code de Gilbert pour afficher le résultat sous forme de courbe.
    Il est superbe ton ZIP.

    Et puisque le sujet semble t'intéresser, voici le code pour 4 types de régression :
    - Régression Linéaire : si le tracé de Y(X) sur papier à graduations décimales s'accumule autour d'une droite,
    - Régression Logarithmique : si le tracé de Y(X) sur papier semi-log sur axe des X forme une droite,
    - Régression Exponentielle : si le tracé de Y(X) sur papier semi-log sur axe des Y forme une droite,
    - Régression Puissance : si le tracé de Y(X) sur papier log-log forme une droite.

    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
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    procedure RegressLineaire(Nuage: TNuage; var A, B, CC: extended; var StrRes: string);
    // Droite Y = A.X + b = droite de régression aux moindres carrés du nuage de points Donné
    // CC = Cœff. de corrélation
    var
      SigX, SigY, SigX2, SigY2, SigXY: extended; op: char;
      Sx, Sy: extended;
      n, i: Integer;
    begin
      n := Length(Nuage); // nombre de points du Nuage
      SigX := 0.0; SigY := 0.0; SigX2 := 0.0; SigY2 := 0.0; SigXY := 0.0;
     
      for i := 0 to n - 1 do
        with Nuage[i] do begin
          SigX := SigX + X;
          SigY := SigY + Y;
          SigX2 := SigX2 + X * X;
          SigY2 := SigY2 + Y * Y;
          SigXY := SigXY + X * Y;
        end;
     
      if (n * SigY2 = SigY * SigY) then begin // Nuage aligné sur Droite Horizontale
        B := SigY / N; A := 0.0;
        StrRes := 'Nuage aligné sur Droite Horizontale'; EXIT;
      end;
      if (n * SigX2 = SigX * SigX) then begin // Nuage aligné sur Droite Verticale
        A := 0; B := 0;
        StrRes := 'Nuage aligné sur Droite Verticale'; EXIT;
      end else begin
        A := ((n * SigXY) - (SigX * SigY)) / ((n * SigX2) - (SigX * SigX)); // Pente
        B := (SigY - A * SigX) / n; // Ordonnée à l'origine
        Sx := sqrt(SigX2 - sqr(SigX) / n);
        Sy := Sqrt(SigY2 - sqr(SigY) / n);
        CC := (SigXY - SigX * SigY / n) / (Sx * sy);
      end;
      if B < 0 then op := '-' else op := '+';
      StrRes := 'y = ' + FloatToStr(A) + '.x ' + op + FloatToStr(abs(B)) + #13#10  // Y = A.X + B
        + 'Cœff. de corrélation = ' + FloatToStr(CC);
    end;
     
    procedure RegressLogarithmique(Nuage: TNuage; var B0, B1: Extended; var StrRes: string);
    // Lien Logarithmique si le tracé de Y(X) sur papier semi-log sur axe des X forme une droite
    var SigX, SigY, SigLnX, SigYLnX, SigLnX2: Extended; i: integer;
    begin
      SigX := 0.0; SigY := 0.0; SigLnX := 0.0; SigYLnX := 0.0; SigLnX2 := 0.0;
      for i := 0 to High(Nuage) do begin
        if Nuage[i].x <= 0.0 then begin
          StrRes := 'Non calculable car présence d''un point X <= 0 : EXIT';
          EXIT;
        end;
        SigX := SigX + Nuage[i].x;
        SigY := SigY + Nuage[i].y;
        SigLnX := SigLnX + ln(Nuage[i].x);
        SigYLnX := SigYLnX + Nuage[i].y * ln(Nuage[i].x);
        SigLnX2 := SigLnX2 + sqr(ln(Nuage[i].x));
      end;
      b1 := (SigYLnX - SigLnX * SigY / length(Nuage)) / (SigLnX2 - sqr(SigLnX) / length(Nuage));
      b0 := (SigY / length(Nuage)) - (b1 * SigLnX / length(Nuage));
      StrRes := 'y = ' + FloatToStr(b0) + ' + ' + FloatToStr(b1) + ' * Ln(x)' + #13#10  // Y = B + A.Ln(X)
        + 'Y = ' + FloatToStr(b0) + ' + ' + FloatToStr(b1 * ln(10)) + ' * Log10(X)';
    end;
     
    procedure RegressExponentielle(Nuage: TNuage; var A, B: Extended; var StrRes: string);
    // Lien Exponentiel si le tracé de Y(X) sur papier semi-log sur axe des Y forme une droite
    // B est alors négligeable
    var SigX, SigY, SigLnY, SigXLnY, SigX2: Extended; i, N: integer; op: char;
    begin
      N := length(Nuage);
      SigX := 0.0; SigY := 0.0; SigLnY := 0.0; SigXLnY := 0.0; SigX2 := 0.0;
      for i := 0 to N - 1 do begin
        if Nuage[i].y <= 0.0 then begin
          StrRes := 'Non calculable car présence d''un point Y <= 0 : EXIT';
          EXIT;
        end;
        SigX := SigX + Nuage[i].x;
        SigY := SigY + Nuage[i].y;
        SigLnY := SigLnY + ln(Nuage[i].y);
        SigXLnY := SigXLnY + Nuage[i].x * ln(Nuage[i].y);
        SigX2 := SigX2 + sqr(Nuage[i].x);
      end;
      A := (N * SigXLnY - SigX * SigLnY) / (N * SigX2 - sqr(SigX));
      B := (SigLnY - A * SigX) / N;
      if abs(B) < 1E-3 then begin
        StrRes := 'Ln(Y) = ' + FloatToStr(A) + ' * X'
      end else begin
        if B < 0 then op := '-' else op := '+';
        StrRes := 'Ln(y) = ' + FloatToStr(A) + '.x ( ' + op + FloatToStr(abs(B)) + ' : négligeable)' + #13#10
          + ' => y = e^(' + FloatToStr(A) + '.x)' + #13#10  // Y = e^(A.X)
          + ' => y = ' + FloatToStr(exp(A)) + '^x';         // Y = (e^A)^X
      end;
    end;
     
    procedure RegressPuissance(Nuage: TNuage; var A, B: Extended; var StrRes: string);
    // Lien de Puissance si le tracé de Y(X) sur papier log-log forme une droite
    var SigX, SigY, SigLnX, SigLnY, SigLnXLnY, SigLnX2: Extended; i, N: integer; op: char;
    begin
      N := length(Nuage);
      SigX := 0.0; SigY := 0.0; SigLnX := 0.0; SigLnY := 0.0; SigLnXLnY := 0.0; SigLnX2 := 0.0;
      for i := 0 to N - 1 do begin
        if Nuage[i].y <= 0.0 then begin
          StrRes := 'Non calculable car présence d''un point Y <= 0 : EXIT';
          EXIT;
        end;
        if Nuage[i].x <= 0.0 then begin
          StrRes := 'Non calculable car présence d''un point X <= 0 : EXIT';
          EXIT;
        end;
        SigX := SigX + Nuage[i].x;
        SigY := SigY + Nuage[i].y;
        SigLnX := SigLnX + ln(Nuage[i].x);
        SigLnY := SigLnY + ln(Nuage[i].y);
        SigLnXLnY := SigLnXLnY + ln(Nuage[i].x) * ln(Nuage[i].y);
        SigLnX2 := SigLnX2 + sqr(ln(Nuage[i].x));
      end;
      A := (N * SigLnXLnY - SigLnX * SigLnY) / (N * SigLnX2 - sqr(SigLnX));
      B := (SigLnY - A * SigLnX) / N;
      if B < 0 then op := '-' else op := '+';
      StrRes := 'Ln(y) = ' + FloatToStr(A) + '.Ln(x) ' + op + ' ' + FloatToStr(abs(B)) + #13#10
        + ' => y = x^(' + FloatToStr(A) + ').e^(' + op + FloatToStr(abs(B)) + ')' + #13#10 // Y = (X^A).e^B
        + ' => y = ' + op + FloatToStr(exp(abs(B))) + '.x^(' + FloatToStr(exp(A)) + ')';   // Y = (e^B).X^A
    end;
    EDIT : Pour améliorer les codes de :
    - RegressLogarithmique(),
    - RegressExponentielle(),
    - et de RegressPuissance(),
    il ne resterait plus qu'à les compléter par le calcul du Coefficient de Corrélation.

    EDIT2 : Oups dans le code de RegressPuissance() remplacer l'instruction qui renvoie la string-Resultat StrRes par celle-ci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    StrRes := 'Ln(y) = ' + FloatToStr(A) + '.Ln(x) ' + op + ' ' + FloatToStr(abs(B)) + #13#10
        + ' => y = x^(' + FloatToStr(A) + ').e^(' + op + FloatToStr(abs(B)) + ')' + #13#10 // Y = (X^A).e^B
        + ' => y = ' + op + FloatToStr(exp(abs(B))) + '.x^(' + FloatToStr(A) + ')'; // Y = (e^B).X^A
    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  13. #13
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 345
    Points : 3 123
    Points
    3 123
    Par défaut
    Merci Gilbert,
    j'avais l'intention de programmer d'autres types de régression (pour le plaisir) et aussi d'afficher le paramètre r pour voir s'il est proche de 1. Dès que j'ai un moment j'inclue tes codes

    A+
    Charly

  14. #14
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Bonjour,

    Charly910 : j'avais l'intention de programmer d'autres types de régressions (pour le plaisir) et aussi d'afficher le paramètre r pour voir s'il est proche de 1. Dès que j'ai un moment j'inclue tes codes
    Bonne idée de calculer r car en présence d'un nuage de points expérimentaux on ne sait pas toujours si leur lien est Linéaire, Logarithmique, Exponentiel ou autre et ce sera donc en calculant r pour chaque type de régression
    cela permettra d'identifier la moins mauvaise c.à.d la meilleure.

    A+ .
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  15. #15
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 345
    Points : 3 123
    Points
    3 123
    Par défaut
    Bonjour,

    Avec les nouveaux éléments de Gilbert : une version améliorée avec les 4 types de régressions et une génération aléatoire de semis de points (à améliorer pour les régressions exponentielles et puissance). J'ai aussi séparé les fonctions de calcul de régression de l'interface.
    A+
    Charly
    CourbeLog2.zip

  16. #16
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Salut,

    Charly910 : une version améliorée avec les 4 types de régressions et une génération aléatoire de semis de points (à améliorer pour les régressions exponentielles et puissance). J'ai aussi séparé les fonctions de calcul de régression de l'interface.
    Toujours aussi belle ton interface... et avec des points déplaçables à la souris
    Par contre pour les calculs du Coeff de Corrélation tu nous tricoté une belle usine à gaz.

    Comme pour la régression linéaire ce calcul s'était fait simplement en trois lignes directement dans la procédure RegressLineaire on peut le faire touts aussi simplement pour les 3 autres, comme suit : (voir instructions en vert)


    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
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    procedure RegressLogarithmique(Nuage: TNuage; var A, B, CC: Extended; var StrRes: string);
    // Lien Logarithmique si le tracé de Y(X) sur papier semi-log sur axe des X forme une droite
    var SigX, SigY, SigLnX, SigYLnX, SigLnX2: Extended; i, n: integer;
      SigX2, SigY2, Sx, Sy: Extended;
    begin
      n := Length(Nuage);
      SigX := 0.0; SigY := 0.0; SigLnX := 0.0; SigYLnX := 0.0; SigLnX2 := 0.0;
      SigX2 := 0.0; SigY2 := 0.0;
      for i := 0 to High(Nuage) do begin
        if Nuage[i].x <= 0.0 then begin
          StrRes := 'Non calculable car présence d''un point X <= 0 : EXIT';
          EXIT;
        end;
        SigX := SigX + Nuage[i].x;
        SigY := SigY + Nuage[i].y;
        SigLnX := SigLnX + ln(Nuage[i].x);
        SigYLnX := SigYLnX + Nuage[i].y * ln(Nuage[i].x);
        SigLnX2 := SigLnX2 + sqr(ln(Nuage[i].x));
        SigX2 := SigX2 + Nuage[i].X * Nuage[i].X;
        SigY2 := SigY2 + Nuage[i].Y * Nuage[i].Y;
      end;
      // Calc. Coeff de Corrélation :
      Sx := sqrt(SigLnX2 - sqr(SigLnX) / n);
      Sy := Sqrt(SigY2 - sqr(SigY) / n);
      CC := (SigYLnX - SigLnX * SigY / n) / (Sx * Sy);
      // Calc. paramètres A et B :
      A := (SigYLnX - SigLnX * SigY / n) / (SigLnX2 - sqr(SigLnX) / length(Nuage));
      B := (SigY / length(Nuage)) - (A * SigLnX / length(Nuage));
      StrRes := 'y = ' + FloatToStr(B) + ' + ' + FloatToStr(A) + ' * Ln(x)' + #13#10 // Y = B + A.Ln(X)
        + 'Y = ' + FloatToStr(B) + ' + ' + FloatToStr(A * ln(10)) + ' * Log10(X)' + #13#10
        + 'Coeff. de Corrélation = ' + FloatToStr(CC);
    end;
    
    procedure RegressExponentielle(Nuage: TNuage; var A, B, CC: Extended; var StrRes: string);
    // Lien Exponentiel si le tracé de Y(X) sur papier semi-log sur axe des Y forme une droite
    // B est alors négligeable
    var SigX, SigY, SigLnY, SigXLnY, SigX2: Extended; i, N: integer; op: char;
      SigY2, SigLnY2, Sx, Sy: Extended;
    begin
      N := length(Nuage);
      SigX := 0.0; SigY := 0.0; SigLnY := 0.0; SigXLnY := 0.0; SigX2 := 0.0; SigY2 := 0.0; SigLnY2 := 0.0;
      for i := 0 to N - 1 do begin
        if Nuage[i].y <= 0.0 then begin
          StrRes := 'Non calculable car présence d''un point Y <= 0 : EXIT';
          EXIT;
        end;
        SigX := SigX + Nuage[i].x;
        SigY := SigY + Nuage[i].y;
        SigLnY := SigLnY + ln(Nuage[i].y);
        SigXLnY := SigXLnY + Nuage[i].x * ln(Nuage[i].y);
        SigX2 := SigX2 + sqr(Nuage[i].x);
        SigY2 := SigY2 + sqr(Nuage[i].y);
        SigLnY2 := SigLnY2 + sqr(ln(Nuage[i].Y));
      end;
      // Calc. Coeff de Corrélation :
      Sx := sqrt(SigX2 - sqr(SigX) / n);
      Sy := Sqrt(SigLnY2 - sqr(SigLnY) / n);
      CC := (SigXLnY - SigX * SigLnY / n) / (Sx * Sy);
      // Calc. paramètres A et B :
      A := (N * SigXLnY - SigX * SigLnY) / (N * SigX2 - sqr(SigX));
      B := (SigLnY - A * SigX) / N;
      if abs(B) < 1E-3 then begin
        StrRes := 'Ln(Y) = ' + FloatToStr(A) + ' * X' + #13#10
          + 'Coeff. de Corrélation = ' + FloatToStr(CC);
      end else begin
        if B < 0 then op := '-' else op := '+';
        StrRes := 'Ln(y) = ' + FloatToStr(A) + '.x ( ' + op + FloatToStr(abs(B)) + ' : négligeable)' + #13#10
          + ' => y = e^(' + FloatToStr(A) + '.x)' + #13#10 // Y = e^(A.X)
          + ' => y = ' + FloatToStr(exp(A)) + '^x' + #13#10 // Y = (e^A)^X
          + 'Coeff. de Corrélation = ' + FloatToStr(CC);
      end;
    end; // RegressExponentielle
    
    procedure RegressPuissance(Nuage: TNuage; var A, B, CC: Extended; var StrRes: string);
    // Lien de Puissance si le tracé de Y(X) sur papier log-log forme une droite
    var SigX, SigY, SigLnX, SigLnY, SigLnXLnY, SigLnX2: Extended; i, N: integer; op: char;
    var Sx, Sy, SigLnY2: Extended;
    begin
      N := length(Nuage);
      SigX := 0.0; SigY := 0.0; SigLnX := 0.0; SigLnY := 0.0; SigLnXLnY := 0.0; SigLnX2 := 0.0; SigLnY2 := 0.0;
      for i := 0 to N - 1 do begin
        if Nuage[i].y <= 0.0 then begin
          StrRes := 'Non calculable car présence d''un point Y <= 0 : EXIT';
          EXIT;
        end;
        if Nuage[i].x <= 0.0 then begin
          StrRes := 'Non calculable car présence d''un point X <= 0 : EXIT';
          EXIT;
        end;
        SigX := SigX + Nuage[i].x;
        SigY := SigY + Nuage[i].y;
        SigLnX := SigLnX + ln(Nuage[i].x);
        SigLnY := SigLnY + ln(Nuage[i].y);
        SigLnXLnY := SigLnXLnY + ln(Nuage[i].x) * ln(Nuage[i].y);
        SigLnX2 := SigLnX2 + sqr(ln(Nuage[i].x));
        SigLnY2 := SigLnY2 + sqr(ln(Nuage[i].y));
      end;
      // Calc. Coeff de Corrélation :
      Sx := sqrt(SigLnX2 - sqr(SigLnX) / n);
      Sy := Sqrt(SigLnY2 - sqr(SigLnY) / n);
      CC := (SigLnXLnY - SigLnX * SigLnY / n) / (Sx * Sy);
      // Calc. paramètres A et B :
      A := (N * SigLnXLnY - SigLnX * SigLnY) / (N * SigLnX2 - sqr(SigLnX));
      B := (SigLnY - A * SigLnX) / N;
      if B < 0 then op := '-' else op := '+';
      StrRes := 'Ln(y) = ' + FloatToStr(A) + '.Ln(x) ' + op + ' ' + FloatToStr(abs(B)) + #13#10
        + ' => y = x^(' + FloatToStr(A) + ').e^(' + op + FloatToStr(abs(B)) + ')' + #13#10 // Y = (X^A).e^B
        + ' => y = ' + op + FloatToStr(exp(abs(B))) + '.x^(' + FloatToStr(A) + ')' + #13#10 // Y = (e^B).X^A
        + 'Coeff. de Corrélation = ' + FloatToStr(CC);
    end;
    ... ça donne un code beaucoup plus compact et plus lisible.

    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  17. #17
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 345
    Points : 3 123
    Points
    3 123
    Par défaut
    C'est vrai, mais mon idée de départ était de pouvoir afficher R indépendamment du calcul de régression, pour pour voir l'afficher avant (et de factoriser la fonction CoeffR). Mais j'ai ensuite changé d'idée !
    A+
    Charly

    @ Gilbert : plutôt :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
      Sx := sqrt(SigLnX2 / n - sqr(SigLnX / n));
      Sy := Sqrt(SigY2 / n - sqr(SigY /n));
      R := (SigYLnX / n - SigLnX * SigY / n / n) / (Sx * Sy);

  18. #18
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Bonjour,

    Charly910 : C'est vrai, mais mon idée de départ était de pouvoir afficher R indépendamment du calcul de régression, pour pour voir l'afficher avant (et de factoriser la fonction CoeffR). Mais j'ai ensuite changé d'idée !
    Bin, on n'est pas à l'abri des conséquences d'un changement d'idée ... mais les changements d'idées ça fait partie de l'évolution.

    Ceci étant il ne resterait plus qu'à compléter les codes par celui de la Régression Polynomiale, nettement plus compliquée.

    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  19. #19
    Membre averti

    Homme Profil pro
    ingénieur, retraité
    Inscrit en
    Février 2007
    Messages
    230
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : ingénieur, retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2007
    Messages : 230
    Points : 332
    Points
    332
    Par défaut
    Bonjour

    Ci-dessous les résultats obtenus avec la régression polynomiale de RegressionGrs.exe (Contribuez/RegPolynomMultiple.zip).

    DevelEquatLogGr.zip

    On notera que la première étape de l'OPTIMISATION a les mêmes résultats qu'Excel.

    PL

  20. #20
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Bonjour,

    Paulfr: Ci-dessous les résultats obtenus avec la régression polynomiale de RegressionGrs.exe (Contribuez/RegPolynomMultiple.zip).
    Ayant téléchargé le code de RegressionGrs j'ai obtenu les résultats suivants sous Delphi 7 Windows 7 :
    [Erreur fatale] ListImp.pas(7): Fichier non trouvé : 'quickrpt.dcu'
    [Erreur fatale] ListImp.pas(7): Fichier non trouvé : 'Qrctrls.dcu'

    A +.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Problème d'équation
    Par irarref dans le forum Maple
    Réponses: 6
    Dernier message: 03/06/2012, 16h22
  2. [Débutant] Petit problème d'équations
    Par Trotterata dans le forum MATLAB
    Réponses: 1
    Dernier message: 06/04/2012, 11h57
  3. problème ode équation différentielles
    Par jamal.obito dans le forum MATLAB
    Réponses: 1
    Dernier message: 26/07/2011, 12h52
  4. Problème simplification équation booléenne
    Par Metallic-84s dans le forum Algorithmes et structures de données
    Réponses: 9
    Dernier message: 09/02/2006, 14h52
  5. Problème d'équations dans l'espace (perspective -> 3D)
    Par Rémiz dans le forum Algorithmes et structures de données
    Réponses: 4
    Dernier message: 19/12/2005, 17h43

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