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 :

Retrait de certaines cases dans un tableau Fortran90


Sujet :

Fortran

  1. #1
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Janvier 2016
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 32
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2016
    Messages : 15
    Points : 11
    Points
    11
    Par défaut Retrait de certaines cases dans un tableau Fortran90
    Bonjour à tous,

    Je débute en Fortran et j'ai quelques difficultés à réaliser ce que je souhaite...
    Alors, je dispose d'un tableau de réels du type :
    0 1 2 3
    1 0 4 5
    2 4 0 6
    3 5 6 0
    Tableau dist

    Je souhaiterais faire "remonter" mes valeurs pour remplir les cases où j'ai des 0, ou plus simplement, retirer les 0 de mon tableau pour obtenir un second tableau de réels du type :
    1 1 2 3
    2 4 4 5
    3 5 6 6
    Tableau temp

    J'ai essayé plusieurs approches qui compilent mais qui ne me donnent pas ce que je souhaite (j'adapte ici mon code à l'exemple ci-dessus, en réalité les dimensions des deux tableaux sont variables mais toujours de la forme (n,n) pour dist et (n-1,n) pour temp).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    real(kind = dp), parameter :: eps = 1.0E-08
    integer(kind = sp) :: i,j
    real(kind = dp), dimension(4,4) :: dist
    real(kind = dp), dimension(3,4) :: temp
    Essai 1 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Do i = 1,4
       Do j = 1,4
         if(abs(dist(j,i)) > eps) then
           temp(j,i) = dist(j,i)
         Endif
       Enddo
     Enddo
    Rq : le "abs" est ici superflu car mon tableau ne contient que des valeurs >= 0 mais je l'ai ajouté en prévision de possibles changements. Cela ne modifie en rien mon code normalement..

    Essai 2 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Do i = 1,4
       Do j = 1,4
         if(abs(dist(j,i)) < eps) cycle
           temp(j,i) = dist(j,i)
       Enddo
     Enddo
    Essai 3 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Do i = 1,4
       Do j = 1,4
         if(i /= j) then
           temp(j,i) = dist(j,i)
         Endif
       Enddo
     Enddo
    Aucune de ces solutions ne fonctionne ... Il y a manifestement un problème au niveau de ma condition qui n'est pas prise en compte mais je ne sais pas pour quelle raison..
    Je précise également que je souhaite effectuer cette manipulation pour ensuite déterminer la valeur minimale pour chaque colonne à l'aide de la fonction minval. Mon tableau dist est un tableau de distance entre points.
    Les 0 correspondent en fait à la distance entre un point et lui-même. Afin de trouver le point le plus proche, il faudrait donc que j'enlève ces 0 pour obtenir la véritable valeur minimale..

    Je vous remercie par avance pour vos réponses et si vous avez besoin de compléments d'information, n'hésitez pas ..!

    Bonne journée à tous

  2. #2
    Membre éclairé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2013
    Messages
    388
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2013
    Messages : 388
    Points : 692
    Points
    692
    Par défaut
    Bonjour.
    Le problème est mal posé. Faut-il supprimer les zéros ou la diagonale principale ?
    S'il s'agit du premier cas, Fortran 90 possède des fonctions intrinsèques permettant des traiter les tableaux. Une solution avec pack, transpose et reshape :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    implicit none
    integer, dimension(:,:), allocatable :: m, t
    m = reshape( (/ 0, 1, 2, 3, 1, 0, 4, 5, 2, 4, 0, 6, 3, 5, 6, 0 /), (/4, 4/) )
    t = transpose(m)
    t = reshape( pack(t, t /= 0), (/3, 4/) )
    print '(4(i3,x))', transpose(t)

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 152
    Points : 191
    Points
    191
    Par défaut
    Hello,

    Pourquoi ne pas plus simplement changer les valeurs "0" en des valeurs arbitrairement grandes ?

    Alors le minval te reverras les valeurs les plus petites autres que "0".

    Tu peux sinon toujours faire le minval à la main en rajoutant une condition d'exclusion sur zero:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    REAL(KIND=8) :: MIN_VAL
    MIN_VAL=1d9 !valeur arbitraire d'initialisation de la valeur minimale
     
    DO J=1,N !ou J=1,M si N/=M
    DO I=1,N 
    IF(TAB(I,J)<MIN_VAL .and. TAB(I,J)/=0d0)
    MIN_VAL=TAB(I,J)
    END DO
    END DO
    La même version gérant le cas où tu veux le min pour chacune des colonnes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    REAL(KIND=8),ALLOCATABLE,DIMENSION(:)::MIN_VAL
     
    ALLOCATE(MIN_VAL(N))
     
    MIN_VAL=1d9 !valeur arbitraire d'initialisation de la valeur minimale
     
    DO J=1,N !ou J=1,M si N/=M
    DO I=1,N 
    IF(TAB(I,J)<MIN_VAL(J) .and. TAB(I,J)/=0d0)
    MIN_VAL(J)=TAB(I,J)
    END DO
    END DO
    En espérant avoir répondu à ta question,

    Marlan

  4. #4
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Janvier 2016
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 32
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2016
    Messages : 15
    Points : 11
    Points
    11
    Par défaut
    Bonjour à vous et merci pour vos réponses.

    _dardanos_ : dans mon cas, enlever les zéros est équivalent à supprimer la diagonale principale car les 0 ne peuvent se trouver que sur cette diagonale. J'avais effectivement trouvé la fonction pack dans des docs mais je ne savais pas bien comment l'utiliser. Si je comprends bien d'après votre exemple, on reverse dans t les valeurs de t différentes de 0 et ce sur 3 lignes et 4 colonnes ..?
    J'ai essayé de l'inclure dans mon code, cela compile mais cela m'indique "Segmentation fault" en sortie lorsque je l'exécute, auriez-vous une idée sur la raison de cet affichage en sortie ?

    Marlan : J'avais pensé à la solution des valeurs arbitrairement grandes aussi et je pense que c'est celle-ci que je vais mettre en œuvre car plus facile ..! Cela fonctionne bien à première vue en tout cas ! Je garde en tête votre exemple du minval à la main qui peut m'être utile également

    Merci en tout cas pour vos réponses, plusieurs solutions pour un même problème c'est toujours mieux

    Bonne journée à tous

  5. #5
    Membre éclairé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2013
    Messages
    388
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2013
    Messages : 388
    Points : 692
    Points
    692
    Par défaut
    Citation Envoyé par delphine2202 Voir le message
    J'ai essayé de l'inclure dans mon code, cela compile mais cela m'indique "Segmentation fault" en sortie lorsque je l'exécute, auriez-vous une idée sur la raison de cet affichage en sortie ?
    Difficile à dire sans voir le code. Voici un 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
    22
    23
    24
    25
    26
    27
    28
    29
    program delete_diag
        implicit none
        integer, dimension(:,:), allocatable :: m, t
     
        m = reshape( (/ 0, 1, 2, 3, 1, 0, 4, 5, &
            2, 4, 0, 6, 3, 5, 6, 0 /), (/4, 4/) )
        call display(m)
        t = clean(m)
        call display(t)
     
    contains
     
    function clean(a)
        integer, dimension(:,:), allocatable :: a
        integer, dimension(:,:), allocatable :: clean
        clean = reshape( pack(a, a /= 0), (/ubound(a,1) - 1, ubound(a,2)/) )
        clean = transpose(clean)
    end
     
    subroutine display(a)
        integer, dimension(:,:), allocatable :: a
        integer :: i, j
        do j = lbound(a, 2), ubound(a, 2)
            print '(100(i2,x))', (a(i, j), i = lbound(a, 1), ubound(a, 1))
        enddo
        print *
    end
     
    end program
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    $ gfortran -Wall delete_diag.f90 
    $  ./a.out 
     0  1  2  3
     1  0  4  5
     2  4  0  6
     3  5  6  0
     
     1  1  2  3
     2  4  4  5
     3  5  6  6
     
    $

  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
    @Dardanos: Ton code requiert un compilateur F2003 (clean = ...), ce qui n'est peut-être pas son cas.

Discussions similaires

  1. Récuperation de certaines valeurs dans un tableau PHP
    Par ns_deux dans le forum PHP & Base de données
    Réponses: 5
    Dernier message: 08/05/2009, 22h06
  2. Réponses: 0
    Dernier message: 13/02/2008, 12h11
  3. Cocher une case dans un tableau
    Par mangood83 dans le forum VBA Word
    Réponses: 0
    Dernier message: 27/08/2007, 09h42
  4. plier/ deplier blocs de cases dans un tableau
    Par deepwrath dans le forum Langage
    Réponses: 8
    Dernier message: 26/04/2007, 08h14
  5. Rotation de case dans un tableau 2D
    Par Oberown dans le forum Algorithmes et structures de données
    Réponses: 20
    Dernier message: 23/08/2006, 16h58

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