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 :

Refactoring de f77 vers f95, problème avec 'goto' et 'continue'


Sujet :

Fortran

  1. #1
    Invité
    Invité(e)
    Par défaut Refactoring de f77 vers f95, problème avec 'goto' et 'continue'
    Bonjour à tous,

    Je souhaiterais convertir cet extrait de code en .f vers .f95:


    do 40 i=0,ndisc

    h = h0
    tin = t(i)

    30 continue

    tout = t(i+1)
    if (type.eq.'IDE') then
    call mebdfi(n,tin,h,y,dy,tout,t(i+1),mf,idid,lout,
    + lwork,work,liwork,iwork,
    + mbnd,maxder,itol,rtol,atol,
    + rpar,ipar,pdervide,residide,ierr)

    elseif (type.eq.'ODE') then
    call mebdfi(n,tin,h,y,dy,tout,t(i+1),mf,idid,lout,
    + lwork,work,liwork,iwork,
    + mbnd,maxder,itol,rtol,atol,
    + rpar,ipar,pdervode,residode,ierr)
    elseif (type.eq.'DAE') then
    call mebdfi(n,tin,h,y,dy,tout,t(i+1),mf,idid,lout,
    + lwork,work,liwork,iwork,
    + mbnd,maxder,itol,rtol,atol,
    + rpar,ipar,pdervdae,residdae,ierr)
    endif

    if (ierr.eq.-1) then
    h = h / 2d0
    idid = -1
    ierr = 0
    goto 30
    elseif (idid.eq.1) then
    if (printsolout) then
    idid = 3
    c -------------------------------------------------
    c The approximation at t0+h0 is printed in the output file
    write(90,formatout)
    + tin, (y(indsol(it)),it=1,nindsol)
    c -------------------------------------------------
    else
    idid = 0
    end if
    goto 30
    elseif (idid.eq.3) then
    c -------------------------------------------------
    c We print only the point in the considered interval
    c [t(i) t(i+1)]
    if ((printsolout).and.(tin.le.tout)) then
    c -------------------------------------------------
    write(90,formatout)
    + tin, (y(indsol(it)),it=1,nindsol)
    end if
    goto 30
    elseif (idid.ne.0) then
    print *, 'MEBDFID: ERROR: ',
    + 'MEBDFI returned IDID = ', idid
    stop
    endif

    c ----------------------------------------------
    c The approximation in t(i+1) is printed in the
    c output file
    if (printsolout) then
    write(90,formatout)
    + tin, (y(indsol(it)),it=1,nindsol)
    idid = 3
    end if
    c ----------------------------------------------

    40 continue


    Mon principal problème est le "30 continue" situé au début, vers lequel plusieurs 'goto 30' renvoient. J'ai tenté des boucles 'do while' pour supprimer les 'goto 30' et le '30 continue', mais en vain.

    Merci d'avance pour votre aide.

  2. #2
    Membre régulier Avatar de rogue-spectre
    Homme Profil pro
    Inscrit en
    Juillet 2011
    Messages
    104
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2011
    Messages : 104
    Points : 122
    Points
    122
    Par défaut
    Bonsoir,

    le seul truc dans ce goto 30, c'est d'éviter le h=h0 et tin=t(i) du coup je te propose de rajouter une variable booléenne, disons have_to_init pour avoir
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    have_to_init=.true.
    DO 40 i=0,ndisc
        if(have_to_init)
            h = h0
            tin = t(i)
        end if
        have_to_init=.true.
    ensuite tu remplace tes goto 30 par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    have_to_init=.false.
    cycle
    afin de ne pas initialiser au début de ta prochaine boucle, l'instruction cycle permettant d'arrêter l’exécution de la boucle i pour passer à la boucle suivante. + remplacer le 40 continue par un END DO. En espérant avoir pu t'aider. Bonne soirée

    PS : penses à mettre ton code entre les balises [ code ] [/code]
    PS2 : à mort les goto Grrrr
    Libérez vos documents http://fr.libreoffice.org/ et vos doigts en tapant en BÉPO http://bepo.fr/wiki/Accueil:, rangez les cartes perforées dans une armoire et GOTO work

  3. #3
    Invité
    Invité(e)
    Par défaut
    Salut rogue-spectre,

    Merci vivement pour ta réponse . Et désolé pour ma réponse tardive, je m'attendais à être prévenu par e-mail de ton message.

    J'ai donc modifié le code (maintenant en f.95), en prenant en compte ton conseil (et an ajoutant "then" après "if(have_to_init)"), ce qui donne:

    Juste après la déclaration du programme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
        logical have_to_init
    Pour le reste:
    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
     
        do i = 0, ndisc
            if(have_to_init) then
                h = h0
                tin = t(i)
            end if
     
            have_to_init = .true.
            tout = t(i+1)
     
            if (type.eq.'IDE') then
                call mebdfi(n,tin,h,y,dy,tout,t(i+1),mf,idid,lout,lwork,work,liwork, &
                    iwork,mbnd,maxder,itol,rtol,atol,rpar,ipar,pdervide,residide,ierr)
            else if (type.eq.'ODE') then
                call mebdfi(n,tin,h,y,dy,tout,t(i+1),mf,idid,lout,lwork,work,liwork, &
                    iwork,mbnd,maxder,itol,rtol,atol,rpar,ipar,pdervode,residode,ierr)
            else if (type.eq.'DAE') then
                call mebdfi(n,tin,h,y,dy,tout,t(i+1),mf,idid,lout,lwork,work,liwork, &
                    iwork,mbnd,maxder,itol,rtol,atol,rpar,ipar,pdervdae,residdae,ierr)
            end if
     
            if (ierr.eq.-1) then
                h = h / 2d0
                idid = -1
                ierr = 0
                have_to_init = .false.
                cycle
     
            elseif (idid.eq.1) then
                if (printsolout) then
                    idid = 3
    ! The approximation at t0 + h0 is printed in the output file
                    write(90,formatout) tin, (y(indsol(it)),it=1,nindsol)
                else
                    idid = 0
                end if
                have_to_init = .false.
                cycle
     
            elseif (idid.eq.3) then
    ! We print only the point in the considered interval [t(i) t(i+1)]
                if ((printsolout).and.(tin.le.tout)) then
                    write(90,formatout) tin, (y(indsol(it)),it=1,nindsol)
                end if
                have_to_init = .false.
                cycle
     
             elseif (idid.ne.0) then
                print *, 'MEBDFID: ERROR: ', 'MEBDFI returned IDID = ', idid
                stop
             endif
     
    ! The approximation in t(i+1) is printed in the output file
            if (printsolout) then
                write(90,formatout) tin, (y(indsol(it)),it=1,nindsol)
                idid = 3
            end if
     
        end do
    Cependant, après compilation et exécution, je n'obtiens pas le même résultat qu'avec le code original (et c'est la seule modification dans tout le programme, sauf error de ma part).
    Peux-tu rapidement vérifier que tout est correct (je re-réflicherai dessus à tête reposée) ?

    Encore merci!
    Et bonne nuit!

    PS : Le refactoring est effectivement pénible !

  4. #4
    Membre régulier Avatar de rogue-spectre
    Homme Profil pro
    Inscrit en
    Juillet 2011
    Messages
    104
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2011
    Messages : 104
    Points : 122
    Points
    122
    Par défaut
    Salut,

    Je regarde ça d'ici demain, en attendant est-ce que tu as bien initialisé ta variable have_to_init à .true. avant ta boucle?… oulala, c'est de ma faute, je me suis planté dans ce que je t'ai dis… puisque le goto ne te fais pas incrémenter ta boucle. En repartant du code initial, il faut je pense plutôt mettre un while avant 'tout = t(i+1)' qui se finit juste avant ' if (printsolout) then'.
    Ça donne un truc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
     while(redo==.true.)
         redo=.false.
    et là où tu as mis dans le code modifié
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    have_to_init=.false.
    cycle
    tu mets
    Je pense qu'on est plus dans le vrai là ! Dis moi si c'est ok pour toi

    Bon WE


    PS : tu peux même mettre une sécurité peux être

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    nb_while=0
     while(redo==.true.)
         redo=.false.
         nb_while=nb_while+1
         if(nb_while>un_grand_nombre_evitant_bouclage_infini)then
             print*,'ERROR INFINITY LOOP'
             STOP
         end if
    Libérez vos documents http://fr.libreoffice.org/ et vos doigts en tapant en BÉPO http://bepo.fr/wiki/Accueil:, rangez les cartes perforées dans une armoire et GOTO work

  5. #5
    Invité
    Invité(e)
    Par défaut


    Salut,

    Merci et bravo ! Cela marche nickel !

    Donc voici le code final, si cela peut aider quelqu'un d'autre:

    Juste après la déclaration du programme:
    Pour le reste:
    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
     
        redo = .true.
     
        do i = 0, ndisc
            h = h0
            tin = t(i)
     
            do while(redo.eqv..true.)
                redo=.false.
                tout = t(i+1)
     
                if (type.eq.'IDE') then
                    call mebdfi(n,tin,h,y,dy,tout,t(i+1),mf,idid,lout,lwork,work,liwork, &
                        iwork,mbnd,maxder,itol,rtol,atol,rpar,ipar,pdervide,residide,ierr)
                else if (type.eq.'ODE') then
                    call mebdfi(n,tin,h,y,dy,tout,t(i+1),mf,idid,lout,lwork,work,liwork, &
                        iwork,mbnd,maxder,itol,rtol,atol,rpar,ipar,pdervode,residode,ierr)
                else if (type.eq.'DAE') then
                    call mebdfi(n,tin,h,y,dy,tout,t(i+1),mf,idid,lout,lwork,work,liwork, &
                        iwork,mbnd,maxder,itol,rtol,atol,rpar,ipar,pdervdae,residdae,ierr)
                end if
     
                if (ierr.eq.-1) then
                    h = h / 2d0
                    idid = -1
                    ierr = 0
                    redo=.true.
     
                elseif (idid.eq.1) then
                    if (printsolout) then
                        idid = 3
    ! The approximation at t0 + h0 is printed in the output file
                        write(90,formatout) tin, (y(indsol(it)),it=1,nindsol)
                    else
                        idid = 0
                    end if
                    redo=.true.
     
                elseif (idid.eq.3) then
    ! We print only the point in the considered interval [t(i) t(i+1)]
                    if ((printsolout).and.(tin.le.tout)) then
                        write(90,formatout) tin, (y(indsol(it)),it=1,nindsol)
                    end if
                    redo=.true.
     
                 elseif (idid.ne.0) then
                    print *, 'MEBDFID: ERROR: ', 'MEBDFI returned IDID = ', idid
                    stop
                 endif
     
    ! The approximation in t(i+1) is printed in the output file
                if (printsolout) then
                    write(90,formatout) tin, (y(indsol(it)),it=1,nindsol)
                    idid = 3
                end if
     
            end do
     
        end do
    Encore merci pour ton aide et bon week-end !

  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
    Quelques améliorations de style ?

    do while(redo.eqv..true.) devrait être écrit do while(redo)

    type.eq.'IDE' devrait être écrit type == 'IDE'

    Encore mieux : l'arbre de branchement sur type.eq.... est un case :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    if (type.eq.'IDE') then
        call mebdfi(n,tin,h,y,dy,tout,t(i+1),mf,idid,lout,lwork,work,liwork, &
            iwork,mbnd,maxder,itol,rtol,atol,rpar,ipar,pdervide,residide,ierr)
    else if (type.eq.'ODE') then
        call mebdfi(n,tin,h,y,dy,tout,t(i+1),mf,idid,lout,lwork,work,liwork, &
            iwork,mbnd,maxder,itol,rtol,atol,rpar,ipar,pdervode,residode,ierr)
    else if (type.eq.'DAE') then
        call mebdfi(n,tin,h,y,dy,tout,t(i+1),mf,idid,lout,lwork,work,liwork, &
            iwork,mbnd,maxder,itol,rtol,atol,rpar,ipar,pdervdae,residdae,ierr)
    end if
    est nettement plus lisible comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    select case(type)
    case('IDE'); call mebdfi(n,tin,h,y,dy,tout,t(i+1),mf,idid,lout,lwork,work,liwork,iwork,mbnd,maxder,itol,rtol,atol,rpar,ipar,pdervide,residide,ierr)
    case('ODE'); call mebdfi(n,tin,h,y,dy,tout,t(i+1),mf,idid,lout,lwork,work,liwork,iwork,mbnd,maxder,itol,rtol,atol,rpar,ipar,pdervode,residode,ierr)
    case('DAE'); call mebdfi(n,tin,h,y,dy,tout,t(i+1),mf,idid,lout,lwork,work,liwork,iwork,mbnd,maxder,itol,rtol,atol,rpar,ipar,pdervdae,residdae,ierr)
    end select

  7. #7
    Invité
    Invité(e)
    Par défaut
    Merci pour ces améliorations de style Sylvain !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Migration 2000 vers 2008 : Problème avec les Users
    Par BenoitM dans le forum Réplications
    Réponses: 1
    Dernier message: 07/12/2009, 14h13
  2. Réponses: 1
    Dernier message: 03/06/2009, 16h14
  3. problème avec GOTO
    Par athmane1988 dans le forum Flash
    Réponses: 0
    Dernier message: 10/02/2009, 15h35
  4. Réponses: 4
    Dernier message: 03/01/2007, 21h25
  5. Problème avec Goto pour un bouton de menu
    Par Klotian dans le forum Flash
    Réponses: 3
    Dernier message: 26/05/2006, 17h49

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