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 :

Ecrire une formule apd programme existant


Sujet :

Fortran

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2012
    Messages : 9
    Par défaut Ecrire une formule apd programme existant
    Bonjour à tous,

    Je suis en train de me casser la tête depuis plusieurs heures à essayer d'écrire une formule en Fortran 90.

    Voici ce que je dois faire :
    Convertir le calcul du jour julien en une fonction (au sens Fortran 90) recevant jour, mois
    et année comme arguments et retourant JD (réel).
    Pour cela je pars d'un programme déjà conçu et qui fonctionne :

    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
    program ToJD
    implicit none
     
    integer::d,m,y
    real::JD,B,A
     
    d=20
    m=2
    y=2012
     
    IF(m<=2) THEN 
    y=y-1
    m=m+12
     
    ENDIF
     
    IF(y>1582) THEN
    A=y/100
    B=2-A+(A/4)
    ELSE
    B=0
     
    ENDIF
     
    JD=INT(365.25*(y+4716))+INT(30.6001*(m+1))+d+B-1524.5
     
    print *,JD
     
    end program

    Ma première idée (c'est la première formule que j'écris d'ailleurs) :

    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
    real function JD(d,m,y)
    implicit none 
     
    integer,intent(in)::d,m,y
    real::B,A
     
     
    IF(m<=2) THEN 
    y=y-1
    m=m+12
     
    ENDIF
     
    IF(y>1582) THEN
    A=y/100
    B=2-A+(A/4)
    ELSE
    B=0
     
    ENDIF
     
    JD=INT(365.25*(y+4716))+INT(30.6001*(m+1))+d+B-1524.5
     
    end function
    Cependant j'ai compris que les variables de la fonction ne peuvent être impliqués dans le "calcul" (ex. y=y-1)

    Je suppose que pour l'algorithme il faut utiliser des nouvelles données mais alors je ne comprends pas bien comment ça peut affecter la fonction et ses variables ?

    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
    real function JD(d,m,y)
    implicit none 
     
    integer,intent(in)::d,m,y
    real::B,A,o,p,q
     
    IF(p<=2) THEN 
    q=q-1
    p=p+12
     
    ENDIF
     
    IF(q>1582) THEN
    A=q/100
    B=2-A+(A/4)
    ELSE
    B=0
     
    ENDIF
     
    o=d
    p=m
    q=y
     
    JD=INT(365.25*(q+4716))+INT(30.6001*(p+1))+o+B-1524.5
     
    end function
    Je sais pas du tout ce que ça vaut le dernier paragraphe ?! Il est sûrement faux :-/

    Au passage est-ce vous pourriez me donner un petit programme qui utilise la fonction en question car j'ai pas encore appris ça mais c'est super utile pour savoir si la fonction fonctionne correctement

    Merci d'avance !

  2. #2
    Membre éprouvé 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
    Par défaut
    Salut,

    …j'ai commencé à écrire quelque chose et paf je découvre des trucs. J'étais persuadé qu'on n'était obligé de mettre des intent pour les fonctions mais en fait oui sinon, avec i une variable d'entrée i=i+1 met bien à jours i… c'est très pervers.
    Donc il faut que tu fasses des copies de tes variables d'entrée éventuellement, ou que tu adapte par exemple ton q=q-1 (ligne 8 dernier code) tu peux le remplacer par q=y-1 car à ce moment tu code q est inconnu, pas assigné donc oui q=q-1 va se faire mais avec la valeur de q que tu trouves dans la mémoire, à savoir n'importe quoi puisque tu ne l'as pas assigné.
    C'est bien je viens d'apprendre qu'on peut faire une déclaration du type
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
        real function toto(lala)
    je connaissais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
        function toto(lala)
             real :: toto
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
       function toto(lala) result(titi)
            real :: titi ! bon la on ne parlera pas de lala

    et parce que c'est tard et que je suis fatigué voici UNE solution, moche, on peut faire mieux mais voilà, c'est la solution du soir.

    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
     
    !>\brief un commentaire pour bien décrire ce que fait la fonction
    FUNCTION lala(dd,mm,yy) 
        IMPLICIT NONE
        ! input
        INTEGER, INTENT(in) :: dd    !< day
        INTEGER, INTENT(in) :: mm  !< month
        INTEGER, INTENT(in) :: yy    !< year
        ! output
         REAL :: lala                         !< pô's friend … or not
       ! local variables
        INTEGER :: d,m,y
     
        ! copy of input variables
        d=dd
        m=mm
        y=yy
     
        ! ici un copié collé des lignes 11 à 25  du premier morceau de code
    END FUNCTION*lala
    les commentaires bizarres c'est pour la documentation par doxygen…

    et le lien du soir pour se détendre : http://www.nojhan.net/geekscottes

    Bonne nuit

  3. #3
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2012
    Messages : 9
    Par défaut
    Salut,

    Merci de ta réponse Malheureusement mon problème n'est pas résolu

    Voici donc la fonction (A et B n'étaient pas défini dans la fonction mais je pense j'ai résolu ce problème)

    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
    FUNCTION JD(dd,mm,yy)
    IMPLICIT NONE
     
    INTEGER, INTENT(in) :: dd
    INTEGER, INTENT(in) :: mm
    INTEGER, INTENT(in) :: yy
     
    REAL :: JD
     
    INTEGER :: d,m,y,A,B
     
    d=dd
    m=mm
    y=yy
     
    IF(m<=2) THEN 
    y=y-1
    m=m+12
     
    ENDIF
     
    IF(y>1582) THEN
    A=y/100
    B=2-A+(A/4)
    ELSE
    B=0
     
    ENDIF
     
    JD=INT(365.25*(y+4716))+INT(30.6001*(m+1))+d+B-1524.5
     
    END FUNCTION
    Pour tester si ça marchait j'ai voulu faire une fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    program testconvertto
    implicit none
    integer :: dd,mm,yy
    integer :: JD
     
    dd = 20
    mm = 2
    yy = 2012
     
    print *, JD(dd,mm,yy)
     
    end program
    Et lorsque je "fortranise" le tout (la commande est-elle correct lorsqu'il y a 2 fichiers ? )
    gfortran fichierformule.f90 fichierprogramme.f90
    Et quand j'exécute le programme j'obtiens : 1242949286 au lieu de 2455977.5 :-/

    D'où provient cette satanée erreur ? ^^

    Merci

    Edit : Merci de ta réponse Grame, je ne l'avais pas vu quand j'ai posté, par contre je suis obligé de repartir de mon programme de conversion qui fonctionne ^^

  4. #4
    Membre expérimenté Avatar de Grame
    Profil pro
    Inscrit en
    Août 2007
    Messages
    148
    Détails du profil
    Informations personnelles :
    Âge : 69
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Août 2007
    Messages : 148
    Par défaut
    Bonjour

    Et lorsque je "fortranise" le tout (la commande est-elle correct lorsqu'il y a 2 fichiers ? )
    oui
    Et quand j'exécute le programme j'obtiens : 1242949286 au lieu de 2455977.5 :-/

    D'où provient cette satanée erreur ? ^^
    Je ne vois pas d'erreur dans ton code. C'est l'algorithme qui est faux.
    Avec l'implémentation que je t'ai donnée, on obtient bien 2455977.5
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    ~/codes/f95/utils> ./a.out 
     Temps julien :    2455977.5    
     Date         :   20  2 2012

  5. #5
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2012
    Messages : 9
    Par défaut
    Citation Envoyé par Grame Voir le message
    C'est l'algorithme qui est faux.
    Avec l'implémentation que je t'ai donnée, on obtient bien 2455977.5
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    ~/codes/f95/utils> ./a.out 
     Temps julien :    2455977.5    
     Date         :   20  2 2012

    Non non mon algorithme n'est pas faux puisque j'obtiens 2455977.5 en l'utilisant dans mon programme (le 1er code cité)

    Est-ce que ça se peut que ça soit Fortran qui déconne ? Un ami m'a dit qu'il avait lu qu'il y a parfois des erreurs avec les fonctions

    Merci

  6. #6
    Membre expérimenté Avatar de Grame
    Profil pro
    Inscrit en
    Août 2007
    Messages
    148
    Détails du profil
    Informations personnelles :
    Âge : 69
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Août 2007
    Messages : 148
    Par défaut
    Bonsoir

    Non non mon algorithme n'est pas faux puisque j'obtiens 2455977.5 en l'utilisant dans mon programme (le 1er code cité)
    ok

    Est-ce que ça se peut que ça soit Fortran qui déconne ? Un ami m'a dit qu'il avait lu qu'il y a parfois des erreurs avec les fonctions
    Change d'amis
    Je n'ai jamais vu que Fortran déconnait, les programmeurs (dont moi), si.

    Sérieusement, en regardant de près, l'erreur saute aux yeux.
    Ta fonction est déclarée REAL
    alors que dans le programme appelant, elle est déclarée INTEGER
    Déclare la en REAL, est ton résultat sera juste.

    Bonne soirée

  7. #7
    Membre expérimenté Avatar de Grame
    Profil pro
    Inscrit en
    Août 2007
    Messages
    148
    Détails du profil
    Informations personnelles :
    Âge : 69
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Août 2007
    Messages : 148
    Par défaut
    Salut

    Voici une implémentation en Fortran 90 :
    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
     
    function julien (jour, mois, annee)
     
    ! Convertit une date civile en temps julien
     
      implicit none
      real :: julien
      integer, intent(in) :: jour, mois, annee
      integer :: ms, an, siecle
     
      if (mois > 2) then
        ms = mois - 3
        an = annee
      else
        ms = mois + 9
        an = annee - 1
      end if
     
      siecle = an / 100
      an = an - 100 * siecle
     
      julien = int(siecle * 146097.0 / 4.0) &
             + int(an * 1461.0/ 4.0) + int((ms * 153.0 + 2.0) / 5.0) &
             + 1721119.0 + jour - 0.5
     
    end function julien

Discussions similaires

  1. Ecrire une formule
    Par Antichoc dans le forum Lotus Notes
    Réponses: 5
    Dernier message: 22/07/2010, 10h35
  2. Ecrire une formule
    Par pekka77 dans le forum Macros et VBA Excel
    Réponses: 7
    Dernier message: 03/04/2008, 18h11
  3. ecrire une formule dans une macro
    Par bouddine dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 19/02/2008, 16h39
  4. Probleme pour ecrire une formule
    Par Dereck07 dans le forum Macros et VBA Excel
    Réponses: 7
    Dernier message: 16/07/2007, 13h32
  5. [VBA-E] ecrire une formule en vba
    Par Huubb dans le forum Macros et VBA Excel
    Réponses: 8
    Dernier message: 25/01/2007, 14h15

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