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

Fortran Discussion :

Triple somme et coefficients binomiaux


Sujet :

Fortran

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2015
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2015
    Messages : 9
    Points : 3
    Points
    3
    Par défaut Triple somme et coefficients binomiaux
    Bonjour, je souhaite écrire un programme qui fait un calcul sur trois sommes avec des coefficients binomiaux. Voici ce que j'ai fait, mais j'ai un doute sur çà. Je vous serai très reconnaissant si vous pouvez m'aider. Merci.

    Pour vous donner une idée de la somme que je veux calculer: Somme = ∑i ∑j ∑k [ bino(i)*bino(j)*bino(k)*exp(x*y*(2*i+j+k)) ]

    integer i,j,k,n
    real bino1,bino2,bino3,Somme

    a=fact(n)
    Somme=0.

    do 30 i=0,5
    bino=fact(5)/(fact(5-i)*fact(i))
    do 30 j=0,8
    bino2=fact(8)/(fact(8-j)*fact(j))
    do 30 k=0,6

    Somme=Somme + bino1*bino2*bino3*exp(x*y*(2*i+j+k))

    30 continue

    stop
    end

    function fact(nn)
    fact=1
    do l=1,nn
    if(nn.eq.0.)then
    fact=1
    else
    fact=fact*l
    endif
    enddo
    end

  2. #2
    Membre averti
    Homme Profil pro
    [SciComp]
    Inscrit en
    Août 2013
    Messages
    134
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : [SciComp]

    Informations forums :
    Inscription : Août 2013
    Messages : 134
    Points : 323
    Points
    323
    Par défaut
    Bonjour,

    Mettre les balises "code" autour du code aurait aidé à plus de lisibilité.
    Sinon, à vue d'oeil, il y a plusieurs erreurs
    - bino1 est déclaré, mais c'est bino qui est initialisé puis bino1 qui est utilisé...
    - bino3 N'est PAS initialisé...
    - x,y non plus
    - Le style des boucles est très old-fashioned
    - Le paradigme de déclaration est changeant: pas d'implicit none, mais tout de même des déclarations de variables. Mieux vaut choisir un implicit none, c'est plus safe. Pareil, je vous conseille d'utiliser les options de compilateurs qui permettent de vérifier que les variables utilisées dans vos expressions ont bien été initialisées (un -Wall -Wextra pour le compilo gfortran commence à checker pas mal de chose et vous aurait permis de voir que bino1, bino3, x et y n'étaient pas initialisées).

    Enfin, ce que vous tentez de calculer est qque chose du style : (1+exp(2*x*y))5(1+exp(x*y))14. Je l'aurais codé comme tel plutôt que de faire des boucles imbriquées.
    NB: Et à la place de faire trois boucles imbriquées, il aurait suffi de faire 3 boucles séparées et de stocker leurs résultats dans 3 variables que vous auriez multiplié à la fin. En termes de performances, c'eut été plus avisé vu que vos boucles, telles qu'implémentées ici, ne dépendent pas les unes (exp d'une somme=prod des exp) des autres.

    Cordialement,
    xflr6

  3. #3
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2015
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2015
    Messages : 9
    Points : 3
    Points
    3
    Par défaut
    Bonjour xflr6, merci beaucoup pour votre réponse. J'ai fait des corrections et apporter plus de précisions sur mon code, en suivant vos conseils. En fait les boucles sont dépendantes les unes des autres. Désolé pour ces erreurs:

    Question: Etant donné que les réels: bino1,bino2,bino3 et bino4 sont des coefficients binomiaux, est-ce que je devrais poser la somme (Somme) de cette façon?

    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
          implicit real (a-h,o-z)
          a= fact(n)
          Somme=0.
     
          do 30 i=0,5
          bino1=fact(5)/(fact(5-i)*fact(i))
     
          do 30 j=0,8
          bino2=fact(8)/(fact(8-j)*fact(j))
     
          do 30 k=0,5-i
          bino3=fact(5-i)/(fact(5-i-k)*fact(k))
     
          do 30 l=0,8-j
          bino4=fact(8-j)/(fact(8-j-l)*fact(l))
     
          Somme=Somme + bino1*bino2*bino3*bino4*exp(x*y*(2*k+l))
     
          30 continue
     
          stop
          end
     
          function fact(nn)
          fact=1
          do m=1,nn
          if(nn.eq.0.)then
          fact=1
          else
          fact=fact*m
          endif
          enddo
          end

  4. #4
    Modérateur

    Profil pro
    Inscrit en
    Août 2006
    Messages
    974
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Août 2006
    Messages : 974
    Points : 1 346
    Points
    1 346
    Par défaut
    Un petit commentaire.

    Tu ne devrais pas définir une fonction factorielle pour calculer des combinaisons car la fonction factorielle produit facilement des overflows. Ta fonction serait overflow avec 36! Il faut calculer directement les combinaisons :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    real function Comb(n,m)
       implicit none
       integer n,m
       integer i
       Comb = 1.0
       if (n <= 0) return
       do i = 0, m - 1
          Comb = Comb * real(n - i) / real(m - i)
       enddo
    end

  5. #5
    Membre averti
    Homme Profil pro
    [SciComp]
    Inscrit en
    Août 2013
    Messages
    134
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : [SciComp]

    Informations forums :
    Inscription : Août 2013
    Messages : 134
    Points : 323
    Points
    323
    Par défaut
    En effet, pour les factorielles, c'est à prendre en compte.

    Pour revenir à la nouvelle proposition de code de Binoga, je ne vois pas d'erreurs flagrantes, mais il reste avec les modifications que vous avez apportées des boucles indépendantes.

    Vous auriez pu couper les sommes i/k et j/l de la sorte :
    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
          Somme=0.
          Somme31=0.
          Somme30=0.
     
          do 30 i=0,5
          bino1=fact(5)/(fact(5-i)*fact(i))
     
          do 30 k=0,5-i
          bino3=fact(5-i)/(fact(5-i-k)*fact(k))
     
          Somme30=Somme30 + bino1*bino3*exp(x*y*(2*k))
       30 continue
     
          do 31 j=0,8
          bino2=fact(8)/(fact(8-j)*fact(j))
     
          do 31 l=0,8-j
          bino4=fact(8-j)/(fact(8-j-l)*fact(l))
     
          Somme31=Somme31 + bino2*bino4*exp(x*y*l)
     
       31 continue
          Somme=Somme30*Somme31
    Peut-être que pour les longueurs de boucles que vous utilisez la différence ne sera pas notable, mais il faut toujours réfléchir et éviter les boucles imbriquées dans un code, elles peuvent rapidement générer des temps d'éxécution prohibifs.

    Après, toujours niveau perf, une bonne pratique serait de sortir les conditions des boucles, comme pour la fonction fact
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
          fact=1
          if(nn.gt.0.)then
              do m=1,nn
                  fact=fact*m
              enddo
          endif
    Enfin, pour éviter les erreurs et améliorer la lisibilité et les futures modifications du code, c'est quand même mieux de faire des implicit none et de déclarer explicitement les variables. ==> Cf l'exemple de Mr Bergeron ci-avant.

    Cordialement,
    xflr6

  6. #6
    Modérateur

    Profil pro
    Inscrit en
    Août 2006
    Messages
    974
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Août 2006
    Messages : 974
    Points : 1 346
    Points
    1 346
    Par défaut
    Citation Envoyé par xflr6 Voir le message
    ...une bonne pratique serait de sortir les conditions des boucles...
    La raison est que les compilateurs modernes optimisent les opérations en utilisant les capacités de pipelining des processeurs. Les branchements conditionnelles dans les boucles empêchent ces optimisations.

    Citation Envoyé par xflr6 Voir le message
    ...mieux de faire des implicit none et de déclarer explicitement les variables...
    Anecdote: Un dénommé Richard Maine de la NASA, membre de l'équipe ayant élaboré la norme Fortran 90, a déjà dit qu'il avait voté pour le maintien des déclarations implicites pour le Fortran 90, mais qu'il regrettait: le langage avait manqué une chance unique de se débarrasser des implicites lors du passage au format source libre en forçant des implicit none automatiques.

    En pratique, on ne devrait JAMAIS écrire du nouveau code qui ne contienne pas de implicit none.

  7. #7
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2015
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2015
    Messages : 9
    Points : 3
    Points
    3
    Par défaut
    Bonjour, je vous remercie infiniment pour toutes vos réponses. Grâce à vos riches conseils j'espère avoir amélioré mon code. Encore merci.

Discussions similaires

  1. Fonction coefficient binomiaux
    Par mous44 dans le forum Général Python
    Réponses: 1
    Dernier message: 26/11/2010, 11h01
  2. [math] somme de plusieurs vecteurs à 3 dimensions
    Par teska dans le forum Mathématiques
    Réponses: 5
    Dernier message: 04/06/2003, 22h40
  3. - [procédure stockée] - Problème de Somme
    Par korrigann dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 20/05/2003, 12h51
  4. [CR ?] Somme d'heure sous Crystal ?
    Par Peter PARKER dans le forum SAP Crystal Reports
    Réponses: 1
    Dernier message: 17/04/2003, 17h24
  5. xsl : sous sommes?
    Par Slash dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 31/03/2003, 14h34

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