Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 7 sur 7
  1. #1
    Invité régulier
    Inscrit en
    juillet 2009
    Messages
    31
    Détails du profil
    Informations forums :
    Inscription : juillet 2009
    Messages : 31
    Points : 6
    Points
    6

    Par défaut Programme de calcul intégral

    Bonjour,
    En application à mon cours de programmation Pascal, j'ai voulu concevoir un programme effectuant le calcul ntégral d'une fonction entre deux bornes suivant la méthode des trapèzes.

    Je me suis vite heurté à un problème, celui de la modélisation de la fonction.Pour y pallier, j'ai donc choisi de traiter uniquement le cas des fonctions polynomiales de dégré inférieur ou égal à 3.Et j'ai procédé par la méthode des trapèzes (pour l'algorithme de calcul).

    J'ai donc conçu ceci.Et il marche,à perfection.J'en suis même assez fier...

    Code :
    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
    program integrale;
    uses wincrt;
     
    {Calcul Intégral d'une fonction polynomiale de dégré 3 par la méthode des trapèzes}
     
    {fonction renvoyant un réel x à la puissance n}
    function puissance(x:real;n:integer):real;
    var i:integer;
        p:real;
    begin
    p:=1;
    if n = 0 then p:=1
    else For i:=1 to n do p:=p*x;
    puissance:=p;
    end;
     
    {fonction renvoyant l'image par f(x) d'un réel x, f étant polynomiale de degré 3}
    function polynome(a,b,c,d,x:real):real;
    var f:real;
    begin
    f:=a*puissance(x,3)+b*puissance(x,2)+c*puissance(x,1)+d;
    polynome:=f;
    end;
     
    {fonction renvoyant la surface d'un trapèze}
    function tarea(b1,b2,h:real):real;
    var area:real;
    begin
    area:=((b1+b2)*h)/2;
    tarea:=area;
    end;
     
    {variables}
    var borneinf,bornesup,h,integral,a,b,c,d:real;
        table: Array[0..1000] of real;
        i,n:integer;
        rec:char;
        cont:boolean;
     
    {Corps du programme}
    begin
     
    cont:=true;
    writeln('Définissez votre polynome de dégré 3 en entrant successivement a,b,c et d');
    read(a,b,c,d);
    writeln('Entrez la borne inférieure, puis supérieure d''intégration');
    read(borneinf,bornesup);
     
    while cont do
    begin
    cont:=false;
    writeln('Entrez le nombre d''intervalles de calcul');
    read(n);
     
    {Remise à zéro de la table}
    for i:=0 to 100 do table[i]:=0;
     
    {calcul et affichage des xi}
    h:=(bornesup-borneinf)/n;
    table[0]:=borneinf;
    For i:=1 to n do table[i]:=table[0]+h*(i);
    For i:=0 to n+1 do writeln(table[i]);
     
    {calcul intégral}
    integral:=0;
    for i:=0 to n-1 do
    integral:=integral+tarea(polynome(a,b,c,d,table[i]),polynome(a,b,c,d,table[i+1]),h);
    writeln('le résultat vaut: ',integral:0:4);
     
    {Possibilité de relancer le programme}
    writeln('Voulez vous recommencer en changeant le nombre d''intervalles de calcul ? (N pour NON, Autre touche pour OUI');
    rec:=readkey;
    if rec = 'n' then cont:= false
    else cont:=true;
    end;

    Je désirerai que:

    - Si des experts passent par là, et on des idées d'améliorations, d'optimisation de calcul, ou de code (ma syntaxe du Pascal est encore boitillante), je suis tout ouvert;
    - Existe t-il une manière de modéliser n'importe quel type de fonction...? Si je voulais par exemple traiter des fonctions polynomiales d'ordre n...? Trigonométriques..? Discontinues en des valeurs sur l'intervalle d'intégration..?

    Merci!

  2. #2
    Membre Expert Avatar de Dr.Who
    Inscrit en
    septembre 2009
    Messages
    980
    Détails du profil
    Informations personnelles :
    Âge : 35

    Informations forums :
    Inscription : septembre 2009
    Messages : 980
    Points : 1 162
    Points
    1 162

    Par défaut

    Code :
    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
    program Project12;
     
    uses crt;
     
    type
      Float = double;
      Int   = LongInt;
      UInt  = LongWord;
     
     
    function Power(const Base: Float; const Exponent: Int): Float;
    var Exp: Int;
        Ret: Float;
    begin
      Ret := Base;
      Exp := Exponent-1;
      if Exp > 0 then
        repeat
          Ret := Ret + Ret;
          dec(Exp);
        until Exp = 0;
      Power := Ret;
    end;
     
    function polynome(const a,b,c,d,x: Float): Float;
    var Ret, x2, x3 : Float;
    begin
      x2  := x + x;
      x3  := x2 + x2;
      Ret := a * x3 + b * x2 + c * x + d;
      polynome := Ret;
    end;
     
    function tarea(const b1,b2,h: Float): Float;
    var ret: Float;
    begin
      ret   := ((b1 + b2) * h) * 0.5;
      tarea := ret;
    end;
     
     
    const
      MaxTable = 1000;
     
    var borneinf, bornesup, integral, h, a, b, c, d  : Float;
        table    : array[0..MaxTable-1] of Float;
        i,n      : Int;
        RK       : char;
        exit     : boolean;
    begin
      exit := false;
     
      writeln('Définissez votre polynome de dégré 3 en entrant successivement a,b,c et d.');
      write('=> ');
      read(a, b, c, d);
     
      writeln('Entrez la borne inférieure, puis supérieure d''intégration.');
      write('=> ');
      read(borneinf, bornesup);
     
      repeat
        repeat
          writeln('Entrez le nombre d''intervalles de calcul');
          write('=> ');
          read(n);
        until n < MaxTable;
     
        {Remise à zéro de la table}
        for i := 0 to MaxTable-1 do
          table[i] := 0;
     
        {calcul et affichage des xi}
        h        := (bornesup-borneinf)/n;
        table[0] := borneinf;
        for i := 1 to n do
          table[i] := table[0] + h * i;
     
        for i := 0 to n+1 do
          writeln(table[i]);
     
        {calcul intégral}
        integral := 0;
        for i := 0 to n-1 do
          integral := integral + tarea(
                                   polynome(a,b,c,d,table[i]),
                                   polynome(a,b,c,d,table[i+1]),
                                   h
                                 );
     
        writeln('le résultat vaut : ', integral:0:4);
     
        {Possibilité de relancer le programme}
        writeln('Voulez vous recommencer en changeant le nombre d''intervalles de calcul ?');
        writeln('touche "N" pour non, tout autre touche pour continuer...');
     
        exit := ReadKey in ['n','N'];
        // ou
    //  case ReadKey of
    //    'n','N': exit := true;
    //  end;
      until exit;
     
    end.
    [ Sources et programmes de Dr.Who | FAQ Delphi | FAQ Pascal | Règlement | Contactez l'équipe ]
    Ma messagerie n'est pas la succursale du forum... merci!

  3. #3
    Invité régulier
    Inscrit en
    juillet 2009
    Messages
    31
    Détails du profil
    Informations forums :
    Inscription : juillet 2009
    Messages : 31
    Points : 6
    Points
    6

    Par défaut

    Merci pour cette réponse...
    Je vois en tout cas une réécriture plus souple du code que je propose.

    Sur la même lancée, comment fonctionne le calcul symbolique (dérivée d'une expression, intégrale d'une fonction, etc...), en termes de programmation...? Est -il envisageable de faire une implémentation en Pascal...?

  4. #4
    Membre Expert Avatar de Dr.Who
    Inscrit en
    septembre 2009
    Messages
    980
    Détails du profil
    Informations personnelles :
    Âge : 35

    Informations forums :
    Inscription : septembre 2009
    Messages : 980
    Points : 1 162
    Points
    1 162

    Par défaut

    Citation Envoyé par seanp223 Voir le message
    Sur la même lancée, comment fonctionne le calcul symbolique (dérivée d'une expression, intégrale d'une fonction, etc...), en termes de programmation...? Est -il envisageable de faire une implémentation en Pascal...?

    cela vas bien au dela de ma comprehension des math

    logiquement, rien n'est impossible (niveau math) en code. mais l'adaptation et l'optimisation demande à ce qu'on comprenne bien le langage de programmation.

    par contre j'ai une erreur dans mon code
    j'ai omis de verifier avec des puissances supérieur à 2!

    si le resultat est bon pour les puissances de 2, il est faut pour les autres!

    2+2 = 4 (2^2)
    4+4 = 8 (2^3)
    8+8 = 16 (2^4)


    mais
    3+3 = 6 =/= 3^2 = 9
    6+6 = 12 =/= 3^3 = 27



    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    function Power(const Base: Float; const Exponent: Int): Float;
    var Exp: Int;
        Ret: Float;
    begin
      Ret := Base;
      Exp := Exponent-1;
      if Exp > 0 then
        repeat
          Ret := Ret * Base;
          dec(Exp);
        until Exp = 0;
      Power := Ret;
    end;
     
    function polynome(const a,b,c,d,x: Float): Float;
    var Ret, x2, x3 : Float;
    begin
      x2  := x * x; 
      x3  := x2 * x;  
      Ret := a * x3 + b * x2 + c * x + d;
      polynome := Ret;
    end;
    [ Sources et programmes de Dr.Who | FAQ Delphi | FAQ Pascal | Règlement | Contactez l'équipe ]
    Ma messagerie n'est pas la succursale du forum... merci!

  5. #5
    Membre Expert

    Homme Profil pro
    Étudiant
    Inscrit en
    juin 2009
    Messages
    936
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Aveyron (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : juin 2009
    Messages : 936
    Points : 1 611
    Points
    1 611

    Par défaut

    Citation Envoyé par seanp223 Voir le message
    Merci pour cette réponse...
    Je vois en tout cas une réécriture plus souple du code que je propose.

    Sur la même lancée, comment fonctionne le calcul symbolique (dérivée d'une expression, intégrale d'une fonction, etc...), en termes de programmation...? Est -il envisageable de faire une implémentation en Pascal...?
    Je sais comment trouver la valeur de la dérivée d'une fonction en un point, ou l'intégrale sur un intervalle, mais pour trouver l'expression littérale, je cherche vite fait mais je vois pas de solution simple.

    Pour la dérivée :

    f'(x)= (f(x+h)-f(x))/h . . . . avec h qui tends vers 0

    Donc tu peux entrer ce calcul, et prendre pour h une valeur très petite ... (différente de 0 ).

    Pour l'intégrale, c'est un peu plus long :

    Tu divises ton intervalle en n parties, puis sur chaque partie qu'on appelle [a,b], tu calcules f(a) et f(b), et tu fais (f(a)+f(b))*(b-a)/2 . Avec ce calcul, tu obtiens l'aire de ton intervalle [a,b]. Tu recommences ce calcul sur toutes les parties de ton intervalle, et tu additionne tout ... Tu obtiendras ton integrale !

    Voir méthode du trapeze ou méthode du point milieu sur wikipédia par exemple !

    Bonne chance

  6. #6
    Expert Confirmé Sénior
    Inscrit en
    août 2006
    Messages
    3 554
    Détails du profil
    Informations forums :
    Inscription : août 2006
    Messages : 3 554
    Points : 4 068
    Points
    4 068

    Par défaut

    Boe,
    Citation Envoyé par mick605 Voir le message
    Pour la dérivée :

    f'(x)= (f(x+h)-f(x))/h . . . . avec h qui tends vers 0

    Donc tu peux entrer ce calcul, et prendre pour h une valeur très petite ... (différente de 0 ).
    Ça ne marchera pas, le problème venant de l'approximation inévitable des nombres réels en informatique.
    Il court en ce moment une espèce de grippe, mais elle ne court pas très vite, car on peut l'attraper sans courir.

  7. #7
    Membre Expert

    Homme Profil pro
    Étudiant
    Inscrit en
    juin 2009
    Messages
    936
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Aveyron (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : juin 2009
    Messages : 936
    Points : 1 611
    Points
    1 611

    Par défaut

    Citation Envoyé par droggo Voir le message
    Boe,

    Ça ne marchera pas, le problème venant de l'approximation inévitable des nombres réels en informatique.
    C'est vrai, je n'y avais pas pensé ...
    On peut quand meme se débrouiller en prenant h pas trop petit pour pas qu'il soit arrondi, non ?
    Sinon, en général, on peut se débrouiller en bidouillant l'expression sans la modifier (passer aux inverses, des trucs comme ca).

    Enfin, j'espere que l'auteur aura plus d'idées que moi !

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •