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 :

Allocation dynamique d'un tableau


Sujet :

Fortran

  1. #1
    Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2010
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2010
    Messages : 40
    Points : 46
    Points
    46
    Par défaut Allocation dynamique d'un tableau
    Bonjour,

    Je m'adresse à vous tous sur ce forum car je n'ai pas trouvé la réponse à ma question.
    En effet, je voudrais savoir s'il est possible d'allouer un tableau dont les dimensions sont lues dans un fichier binaire et de retourner ce tableau en sortie.

    Je sais qu'allouer un tableau et lui attribuer ses dimensions dynamiquement en les récupérant dans un fichier sont possible mais je sais que l'instruction ALLOCATABLE n'est pas compatible avec l'instruction INTENT.

    Est ce que quelqu'un a déjà réalisé quelque chose de similaire?

    Merci d'avance pour vos réponses.

  2. #2
    Membre éclairé Avatar de genteur slayer
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2002
    Messages
    710
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2002
    Messages : 710
    Points : 825
    Points
    825
    Par défaut
    tu peux passer par un module:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    module toto
      real(kind=8),dimension(:),allocatable :: titi
    end module toto
    puis dans une autre routine:

    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
     
    subroutine litfichier
    use toto
    implicit none
     
    ...
    open(unit=15,.....)
      read(15)taille
    ...
      if (allocated(titi)) deallocate(titi)
      allocate(titi(taille))
    ...
      read(15)titi
    ...
      return
    end subroutine litfichier
    ensuite tu n'a qu'à charger le module toto dans la/les routine qui utilise le tableau titi !!!
    il n'y a que ceux qui savent qui ne savent pas qu'ils savent...
    Libere-toi hacker, GNU's Not Unix!!!

  3. #3
    Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2010
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2010
    Messages : 40
    Points : 46
    Points
    46
    Par défaut
    Merci pour cette réponse
    J'ai donc suivi votre méthode qui m'a l'air vraiment bien. Mais j'avoue que j'ai du mal à voir comment déclarer le tableau et dimensions dans chaque fonction.

  4. #4
    Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2010
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2010
    Messages : 40
    Points : 46
    Points
    46
    Par défaut
    J'ai essayé d'inclure tes suggestions dans mon code mais j'obtiens les erreurs suivante :

    1) Number of subscripts declared and used do not match (PROJ)
    2) Illegal structure component reference.

    PROJ correspond à titi dans ton exemple.
    La deuxième erreur intervient lorsque j'essai de lire dans le fichier (je récupère ce que je lis dans le tableau PROJ avec l'instruction READ).

    Je ne comprend pas du tout la première erreur. Auriez-vous une idée de ce à quoi elle peut correspondre?

  5. #5
    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 Dreyliciouss Voir le message
    1) Number of subscripts declared and used do not match (PROJ)
    C'est un problème de dimension. Tu fais référence à un tableau avec un nombre d'indice différent du nombre de dimensions déclaré. Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    real, dimension(:,:) :: Tableau ! 2 dim
    ...
    Tableau(3) = ... ! 1 dim

  6. #6
    Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2010
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2010
    Messages : 40
    Points : 46
    Points
    46
    Par défaut
    Nikel! L'erreur a disparue par contre, à la dernière ligne de code lorsque j'essai d'allouer les dimensions a et b lues précédemment dans le fichier, il me dit "ALLOCATE argument must be ALLOCATABLE or POINTER. (PROJ)". Cela vient sans doute de la déclaration de a et b.

    Mais quand je déclare a et b avec la ligne suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    INTEGER, ALLOCATABLE :: a,b
    Il me dit :

    ALLOCATABLE or POINTER array-spec must be deferred shape. (A)
    ALLOCATABLE or POINTER array-spec must be deferred shape. (A)

    et l'erreur précédente est toujours présente. Je ne sais pas comment les déclarer correctement.

  7. #7
    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
    Ce n'est pas A et B qui doivent avoir l'attribut allocatable, c'est Proj...

  8. #8
    Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2010
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2010
    Messages : 40
    Points : 46
    Points
    46
    Par défaut
    Proj est déjç défini comme alloctable dans le module toto. Dois-je le redéfinir comme allocatable dans la routine où je l'utilise aussi?

  9. #9
    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
    ... Euh.....

    As-tu un implicit none dans la routine ? Sinon, ajoute le.

    (Si Proj a l'attribut allocatable et que le compilateur te dit que Proj doit avoir l'attribut allocatable, c'est qu'il ne voit possiblement pas la variable Proj du module)

  10. #10
    Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2010
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2010
    Messages : 40
    Points : 46
    Points
    46
    Par défaut
    Oui ma routine contient bien "implicit non"
    Comme tu l'as dit précédemment j'ai l'impression qu'il ne voit pas la variable Proj du module puisqu'il me dit : "No implicit data type given for this symbol (PROJ)"

  11. #11
    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
    As-tu bien un use du module dans la routine (ou dans le module contenant routine s'il y a lieu) ?

    Si oui, as-tu une clause "only" sur le use ? si oui, Proj est dans la liste ?

    As-tu un "private" affectant Proj dans le module ?

  12. #12
    Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2010
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2010
    Messages : 40
    Points : 46
    Points
    46
    Par défaut
    J'ai bien une instruction "use toto" dans ma routine. Par contre, je n'ai pas de clause "only" sur le use et je n'ai pas non plus de "private" affectant le Proj dans le module.

  13. #13
    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
    Je ne vois pas ce qui ne fonctionne pas :
    • Proj est défini allocatable dans le module toto.
    • Il n'y a pas de private dans toto.
    • Il y a un implicit none dans la routine
    • Il y a un use toto dans la routine
    • Il n'y a pas de variable Proj masquant celle de toto dans la routine (sinon il n'y aurait pas de message "No implicit data type given for this symbol (PROJ)"

    Peux-tu nous fournir le code, ou une version simplifiée produisant le problème ?

  14. #14
    Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2010
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2010
    Messages : 40
    Points : 46
    Points
    46
    Par défaut
    J'ai vérifié et oui tout est ok dans ce que tu viens de dire donc je ne comprend pas vraiment non plus.

    Voici le code :
    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
     
    C -*- f90 -*-
     
           MODULE TOTO
              REAL,DIMENSION(:,:),ALLOCATABLE :: PROJ
           END MODULE TOTO
     
     
           SUBROUTINE LIREPROJ(FICPRJ,PROJ)
     
           USE TOTO
     
           IMPLICIT NONE   
     
           CHARACTER*150, INTENT(IN) :: FICPRJ   
           INTEGER :: a,b
           INTEGER :: NENRG
           INTEGER :: II,J
           INTEGER*4 :: TailleEnreg
     
           TailleEnreg   = 4*256
           NENRG = 0
     
           OPEN(UNIT=20,FILE=FICPRJ,FORM='UNFORMATTED',RECL=TailleEnreg,
         & STATUS='OLD',ACCESS='DIRECT')
     
     
    ! ~~~~~~~~~~~ Lecture de l'entete dans le fichier de sortie proj ~~~~~~~~~~~~~~
     
              READ (UNIT=20,REC=1)  a
              READ (UNIT=20,REC=2)  b
     
              NENRG=2
     
              if (allocated(PROJ)) deallocate(PROJ)
              allocate(PROJ(a,b))
     
    ! ~~~~~~~~ Lecture des données dans le fichier ~~~~~~~~~~~~~
     
              print* ,'Lancement de la lecture de ',FICPRJ
              DO J = 1 , a
     
                 NENRG = NENRG + 1
                 READ (20,REC=NENRG) (PROJ(J,II),II=1,b)
              END DO
     
              print* ,'Le fichier ',FICPRJ, 'a bien été lu'
     
           CLOSE(20)
     
           RETURN 
           END SUBROUTINE LIREPROJ

  15. #15
    Membre éclairé Avatar de genteur slayer
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2002
    Messages
    710
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2002
    Messages : 710
    Points : 825
    Points
    825
    Par défaut
    moi je vois des choses qui me dérange... je dis pas que c'est pas possible mais je les trouves bizarre:
    dans la structure de la routine tu écrit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SUBROUTINE LIREPROJ(FICPRJ,PROJ)
    moi j'aurais donné un autre nom que 'PROJ' déjà...

    mais surtout, je ne l'aurais même pas mis dans la déclaration... juste
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SUBROUTINE LIREPROJ(FICPRJ)
    parce que toute routine/fonction/program qui contient un 'use toto' connait automatiquement PROJ du coup pas besoin de le mettre en paramètre!!!

    le reste de ta routine me semble correct...

    je sais pas si c'est cela mais il est possible d'avoir un conflit de nom entre le PROJ du module et le PROJ des paramètre (qui n'est pas vraiment déclaré dans la routine hormis à travers le module... ça me semble louche...
    il n'y a que ceux qui savent qui ne savent pas qu'ils savent...
    Libere-toi hacker, GNU's Not Unix!!!

  16. #16
    Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2010
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2010
    Messages : 40
    Points : 46
    Points
    46
    Par défaut
    Le problème c'est que je veux récupérer le tableau PROJ en sortie avec les bonnes dimensions.
    Là, la routine marche bien en enlevant PROJ des paramètres. En revanche en sortie, l'ordinateur ne trouve pas l'objet retourné et je ne peux pas exploiter le tableau après l'utilisation de la routine.

  17. #17
    Membre éclairé Avatar de genteur slayer
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2002
    Messages
    710
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2002
    Messages : 710
    Points : 825
    Points
    825
    Par défaut
    pour le récupéré, il suffit de mettre 'use toto' dans la routine qui utilise...

    si tu veut les tailles il y a un moyen simple:
    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
     
    MODULE TOTO
        REAL,DIMENSION(:,:),ALLOCATABLE :: PROJ
        INTEGER NX,NY
    contains
     
         subroutine allocate_proj(NN,MM)
           implicit none
           integer,intent(in)::NN,MM
           if (allocated(PROJ)) deallocate(PROJ)
           Nx=NN
           Ny=MM
           allocate(PROJ(Nx,NY))
         end subroutine allocate_proj
     
    END MODULE TOTO
    et tu utilise la routine allocate_proj pour l'allocation, ainsi les taille sont connues...
    mais tu peux également utiliser les fonctions SHAPE, SIZE ...etc....

    et ta routine de lecture n'a pas besoin de sortie... je vois pas où est le problème? c'est parce que c'est utilisé par un bout dont tu n'a pas le code???
    il n'y a que ceux qui savent qui ne savent pas qu'ils savent...
    Libere-toi hacker, GNU's Not Unix!!!

  18. #18
    Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2010
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2010
    Messages : 40
    Points : 46
    Points
    46
    Par défaut
    C'est moi qui veut que la routine puisse renvoyer en sortie le tableau afin de pouvoir l'exploiter dans un autre programme.
    Il ne s'agit pas de récupérer le tableau dans la routine, ca la routine le fait déja.

  19. #19
    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
    Le problème est effectivement que le paramètre Proj masque la variable Proj du module toto.

    Compte tenu de ce que te suggère genteur slayer et de ta réponse, tu dois t'interroger sur tes besoins et le design à utiliser.

    Si tu utilises l'approche module, tu dois accéder à Proj via le module partout où tu en as besoin. Par exemple :
    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
     
    MODULE TOTO
         REAL,DIMENSION(:,:),ALLOCATABLE :: PROJ
         END MODULE TOTO
     
    SUBROUTINE LIREPROJ(FICPRJ)
     
       USE TOTO
       ...
       allocate(PROJ(a,b))
       END SUBROUTINE LIREPROJ
     
    subroutine Appelante
       use toto
       ...
       call LireProj(...)
       call UneAutreRoutine(Proj) ! Là, Proj est un paramètre. 
                                           ! Il ne sera donc pas accédé
                                           ! par le module toto...
       xyz = f(Proj)
    ...
    Cette structure est la plus simple si une seule variable Proj peut exister dans ton programme.

    Si tu veux cependant que LireProj puisse lire plusieurs fichiers et retourner plusieurs tableau Proj comme par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
       call LireProj('Fichier1',Proj1)
       call LireProj('Fichier2',Proj2)
       call LireProj('Fichier3',Proj3)
       xyz = f(Proj1+Proj2+Proj3)
       ...
    alors tu dois utiliser un paramètre et non passer par un module.

  20. #20
    Membre éclairé Avatar de genteur slayer
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2002
    Messages
    710
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2002
    Messages : 710
    Points : 825
    Points
    825
    Par défaut
    si tu tiens absolument à utiliser le tableau en paramètres tu peux utiliser les common... mais c'est pas très joli... il y a les attribut SAVE aussi, mais je ne sais pas très bien comment on les utilise.

    mais si tu vaut utiliser dans un autre programme alors, c'est une routine d'écriture dans un fichier que tu as besoin, la lecture se fera à partir de l'autre programme....
    si par hasard par 'programme' tu entend 'subroutine' dans le même 'program' alors justement tu n'a pas besoin de faire une sortie par paramètre, il te suffira de mettre use toto dans l'autre subroutine...
    il n'y a que ceux qui savent qui ne savent pas qu'ils savent...
    Libere-toi hacker, GNU's Not Unix!!!

Discussions similaires

  1. [debutant] allocation dynamique d'un tableau.
    Par méphistopheles dans le forum Débuter
    Réponses: 3
    Dernier message: 16/03/2007, 12h45
  2. Réponses: 2
    Dernier message: 05/03/2007, 18h37
  3. Réponses: 67
    Dernier message: 13/02/2007, 18h08
  4. Réponses: 13
    Dernier message: 01/10/2006, 00h25
  5. [PRO*C] Allocation dynamique d'un tableau de VARCHAR
    Par NéalZheimer dans le forum Interfaces de programmation
    Réponses: 5
    Dernier message: 07/07/2006, 13h02

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