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 :

F90 - problème compréhension fonction retournant un array


Sujet :

Fortran

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite

    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    665
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2010
    Messages : 665
    Par défaut F90 - problème compréhension fonction retournant un array
    Bonjour,

    Je suis assez mauvais en Fortran. Je cherche à coder une fonction qui retourne un array, sans succès. J'ai bien entendu cherché des exemples sur internet, mais là encore sans succès. Ci-dessous l'un de ces exemples qui est donc sensé fonctionner :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    real function times2(x,n) result(y)
        real, intent(in) :: x(n)
        integer, intent(in) :: n
        real  :: y(n)
     
        y = 2*x
    end function
    Je me perds dans les différentes façons de déclarer les variables et les fonctions, alors que peut-être le soucis est ailleurs. Je code donc en Fortran 90. Mon compilateur est Intel Fortran XE 14.0.4.237. Le fichier de debug généré est le suivant :

    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
     
     
    Compiling with Intel(R) Visual Fortran Compiler XE 14.0.4.237 [IA-32]...
    ifort /nologo /debug:full /Od /warn:interfaces /module:"Debug\\" /object:"Debug\\" /Fd"Debug\vc100.pdb" /traceback /check:bounds /check:stack /libs:dll /threads /dbglibs /c /Qvc10 /Qlocation,link,"c:\Program Files (x86)\Microsoft Visual Studio 10.0\Intel Fortran\Microsoft Files\VC\\bin" "C:\Users\cc\Documents\RetD\DP_Fortran\Tests_Math\Operations_matricielles\Code_Source\Mod_Thruster.f90"
    C:\Users\cc\Documents\RetD\DP_Fortran\Tests_Math\Operations_matricielles\Code_Source\Mod_Thruster.f90(55): error #6419: This scalar name is invalid in this context.   [Y]
                real  :: y(n)
    ---------------------^
    C:\Users\cc\Documents\RetD\DP_Fortran\Tests_Math\Operations_matricielles\Code_Source\Mod_Thruster.f90(7): error #6404: This name does not have a type, and must have an explicit type.   [GET_THRUST]
        public :: get_thrust
    --------------^
    C:\Users\cc\Documents\RetD\DP_Fortran\Tests_Math\Operations_matricielles\Code_Source\Mod_Thruster.f90(57): error #6366: The shapes of the array expressions do not conform.   [Y]
                y = 2*x
    ------------^
    compilation aborted for C:\Users\cc\Documents\RetD\DP_Fortran\Tests_Math\Operations_matricielles\Code_Source\Mod_Thruster.f90 (code 1)
     
    ifort /nologo /debug:full /Od /warn:interfaces /module:"Debug\\" /object:"Debug\\" /Fd"Debug\vc100.pdb" /traceback /check:bounds /check:stack /libs:dll /threads /dbglibs /c /Qvc10 /Qlocation,link,"c:\Program Files (x86)\Microsoft Visual Studio 10.0\Intel Fortran\Microsoft Files\VC\\bin" "C:\Users\cc\Documents\RetD\DP_Fortran\Tests_Math\Operations_matricielles\Code_Source\dpl_dll.f90"
    C:\Users\cc\Documents\RetD\DP_Fortran\Tests_Math\Operations_matricielles\Code_Source\dpl_dll.f90(138): error #5082: Syntax error, found ',' when expecting one of: <END-OF-STATEMENT> ;
                thrust_arr(1) = 5.0d0, thrust_arr(2) = 11.0d0
    ---------------------------------^
    C:\Users\cc\Documents\RetD\DP_Fortran\Tests_Math\Operations_matricielles\Code_Source\dpl_dll.f90(140): error #6404: This name does not have a type, and must have an explicit type.   [TIMES2]
                res = times2(thrust_arr, 3)
    ------------------^
    compilation aborted for C:\Users\cc\Documents\RetD\DP_Fortran\Tests_Math\Operations_matricielles\Code_Source\dpl_dll.f90 (code 1)
     
     
    dpl_dll - 7 error(s), 0 warning(s)
    J'ai essayé un peu tout ce qui me passe par la tête : sans result(), déclarer ou pas le résultat dans la fonction, ajouter le type ou pas devant function, etc..

    Est-ce que c'est moi qui déconne ou c'est un problème de compilation ? Sachant que je parviens sans soucis à faire une fonction similaire mais qui renvoi un scalaire à la place.

    J

  2. #2
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 746
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 746
    Par défaut
    Hello,

    Un nom ne peut être déclaré qu'une seule fois dans une portée donnée. Le compilateur signale donc un conflit de nom. Le nom y est déjà réservé en tant que "poignée" pour la valeur de retour, et tu essaies de l'utiliser pour définir une nouvelle entité.
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  3. #3
    Membre émérite

    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    665
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2010
    Messages : 665
    Par défaut
    Bonjour et merci Fred.

    Je me mélange sur les déclarations. Ton commentaire m'a incité à rechercher comment déclarer le type de la fonction (ou devrais-je dire le type du résultat de la fonction). En ce faisant j'ai trouvé une référence à un standard :

    if the function result is an array, allocatable, or a pointer, this shall be specied by specifications of the name of the result variable within the function body

    Donc au lieu d'essayer de définir le type devant le mot clé function, il faudrait définir le type implicitement dans la fonction, et donc (j'ai l'impression) utiliser ce style :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    function times2(x,n)
        real, intent(in) :: x(n)
        integer, intent(in) :: n
        real, dimension(n)  :: times2
     
        times2 = 2*x
     
    end function
    ça compile. Maintenant, est-ce que c'est la bonne méthode ? Par bonne je veux dire idiomatique ?

    J

  4. #4
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 746
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 746
    Par défaut
    Ça me donne l'impression d'un code du fortran 77 adapté au fortran 90

    Que donne ce code ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    function times2(x) result(y)
        real, intent(in) :: x(:)
        real :: y(size(x))
     
        y = 2.0 * x
    end function times2
    À tester !
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  5. #5
    Membre émérite

    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    665
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2010
    Messages : 665
    Par défaut
    Cette version fonctionne effectivement. Conceptuellement, qu'elle est la différence entre déclarer la variable y d'une taille fixe dans la première version et d'une taille identique à l'entrée dans la seconde ? Je t'avoue ne pas saisir pourquoi ce code ne compile pas (avec ou sans real en début de fonction) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    real function times2(x,n) result(y)
        real, intent(in) :: x(n)
        integer, intent(in) :: n
        real  :: y(n)
     
        y = 2*x
    end function
    Mais celui-ci oui :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    function times2(x) result(y)
        real, intent(in) :: x(:)
        real :: y(size(x))
     
        y = 2.0 * x
    end function times2
    Merci en tout cas !

    J

  6. #6
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 746
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 746
    Par défaut
    Hello,

    Le compilateur est face à une contradiction : le nom de la fonction times2 est associé à un type scalaire, mais la variable de résultat y que tu essaies d'utiliser est un tableau. C'est pour cela qu'il te dit que y (This scalar name) est invalide dans ce contexte (is invalid in this context).
    L'erreur #6366 (The shapes of the array expressions do not conform) sur la ligne y = 2*x est une conséquence directe de la première. Comme le compilateur pense que y est un scalaire, il refuse de lui assigner un tableau (2*x).
    Quand on utilise la clause result(y), il ne faut pas déclarer le type de la fonction sur la première ligne. Le type de la fonction est automatiquement déduit du type de la variable de résultat.

    Si je devais corriger ton ancien code, bien moins bon ça serait,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    ! On retire "real" du début
    function times2(x,n) result(y)
        integer, intent(in) :: n
        real, intent(in) :: x(n)
        real :: y(n)  ! La fonction sait maintenant qu'elle retourne un tableau de réels de taille n
     
     
        y = 2.0 * x
    end function times2
    Tu vois à l’œil que ce code est bien moins sexy et intuitif
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

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

Discussions similaires

  1. Retourner un array dans une fonction
    Par Hatsrog dans le forum Langage
    Réponses: 4
    Dernier message: 06/03/2015, 23h33
  2. Réponses: 10
    Dernier message: 15/04/2014, 19h49
  3. [MySQL] Retourner un array d'une fonction et l'utiliser
    Par andaman dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 18/10/2013, 07h07
  4. fonction retourne array
    Par the_nmy dans le forum Débuter
    Réponses: 5
    Dernier message: 25/09/2011, 16h31
  5. [XL-2000] fonction personnelle qui retourne un array
    Par SpaceFrog dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 02/09/2010, 13h44

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