4 votes

Indexer plusieurs éléments non adjacents d'un tableau Fortran

Existe-t-il un moyen en Fortran d'accéder à plusieurs éléments d'un tableau sans utiliser une boucle ?

Par exemple, un tableau de 100 éléments

real(100) :: a

Puis-je faire quelque chose comme ça pour accéder aux éléments 1,4,7,54,81 qui ne suivent pas un pas régulier ?

a(1,4,7,54,81)= 3.21423

7voto

ewcz Points 9060

Vous pourriez utiliser un indice de vecteur : a( (/1,4,7,54,81/) )= 3.21423

2voto

francescalus Points 16310

Comme indiqué précédemment, un tableau peut être utilisé comme les index d'un tableau. C'est ce qu'on appelle un indice vectoriel.

A([1,4,7,54,81]) = 3.21423

définit les éléments donnés à cette valeur. (C'est la même chose que la réponse précédente mais en utilisant la notation Fortran 2003+/moderne des constructeurs de tableaux).

Le tableau peut être n'importe quel tableau de rang 1, comme une variable ou une expression :

integer :: idx(5)=[1,4,7,54,81]
A(idx) = 3.21423
A(idx-1+1) = 3.21423

Bien entendu, les indices vectoriels sont utiles dans d'autres contextes, comme le référencement :

print *, A(idx)
call sub(A(idx))
A(idx) = A(idx+1) + 5

Toutefois, les sections de tableau avec des indices vectoriels sont soumises à diverses restrictions, telles que :

  1. il ne s'agit pas toujours d'arguments à une procédure ;
  2. un pointeur peut ne pas pointer vers eux ;
  3. toutes ces sections ne peuvent être affectées.

Dans le troisième cas, si le même indice apparaît plus d'une fois dans l'indice, nous ne pouvons pas le définir. Ainsi,

print *, A([1,5,1])

est autorisé, mais

A([1,5,1]) = 3.

ne l'est pas.

-2voto

Holmz Points 641

RESHAPE et WHERE valent la peine d'être regardés. Si vous déterminez les éléments à "retirer", vous pouvez peut-être ALLOUER une nouvelle variable et placer les éléments de A dans B. Peut-être quelque chose comme ceci :

REAL,    DIMENSION(100)            :: A
LOGICAL, DIMENSION(100)            :: A_Mask
INTEGER                            :: SizeB
REAL,    DIMENSION(:), ALLOCATABLE :: B
!...
A_Mask = .FALSE.
WHERE(A > 1.0)
  A_Mask = .TRUE.
ENDWHERE
SizeB = SUM(A_Mask)
!... then allocate B and fill it.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X